From ec581cd5903d1a1fd129d647daa289a081b2dd1a Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Fri, 7 Apr 2017 12:50:33 -0700 Subject: [PATCH 01/21] Update TSI with new non-blocking TSI interfaces. --- Makefile | 3 + src/core/tsi/fake_transport_security.c | 1 + src/core/tsi/ssl_transport_security.c | 1 + src/core/tsi/transport_security.c | 44 +++ src/core/tsi/transport_security.h | 22 ++ src/core/tsi/transport_security_adapter.c | 230 ++++++++++++++++ src/core/tsi/transport_security_adapter.h | 55 ++++ src/core/tsi/transport_security_interface.h | 279 ++++++++++++++++---- test/core/tsi/transport_security_test.c | 2 + 9 files changed, 585 insertions(+), 52 deletions(-) create mode 100644 src/core/tsi/transport_security_adapter.c create mode 100644 src/core/tsi/transport_security_adapter.h diff --git a/Makefile b/Makefile index 91a74f354e8..cbf38709911 100644 --- a/Makefile +++ b/Makefile @@ -2987,6 +2987,7 @@ LIBGRPC_SRC = \ src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ + src/core/tsi/transport_security_adapter.c \ src/core/ext/transport/chttp2/server/chttp2_server.c \ src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \ src/core/ext/filters/client_channel/channel_connectivity.c \ @@ -3330,6 +3331,7 @@ LIBGRPC_CRONET_SRC = \ src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ + src/core/tsi/transport_security_adapter.c \ src/core/ext/transport/chttp2/client/chttp2_connector.c \ src/core/ext/filters/load_reporting/load_reporting.c \ src/core/ext/filters/load_reporting/load_reporting_filter.c \ @@ -19257,6 +19259,7 @@ src/core/plugin_registry/grpc_plugin_registry.c: $(OPENSSL_DEP) src/core/tsi/fake_transport_security.c: $(OPENSSL_DEP) src/core/tsi/ssl_transport_security.c: $(OPENSSL_DEP) src/core/tsi/transport_security.c: $(OPENSSL_DEP) +src/core/tsi/transport_security_adapter.c: $(OPENSSL_DEP) src/cpp/client/cronet_credentials.cc: $(OPENSSL_DEP) src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP) src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP) diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c index 822fad51cb3..1836beefc42 100644 --- a/src/core/tsi/fake_transport_security.c +++ b/src/core/tsi/fake_transport_security.c @@ -499,6 +499,7 @@ static const tsi_handshaker_vtable handshaker_vtable = { fake_handshaker_extract_peer, fake_handshaker_create_frame_protector, fake_handshaker_destroy, + NULL, }; tsi_handshaker *tsi_create_fake_handshaker(int is_client) { diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index a0325cc1835..c4dba002f8b 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -1049,6 +1049,7 @@ static const tsi_handshaker_vtable handshaker_vtable = { ssl_handshaker_extract_peer, ssl_handshaker_create_frame_protector, ssl_handshaker_destroy, + NULL, }; /* --- tsi_ssl_handshaker_factory common methods. --- */ diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c index 67ebe1b1f30..71f82958043 100644 --- a/src/core/tsi/transport_security.c +++ b/src/core/tsi/transport_security.c @@ -73,6 +73,8 @@ const char *tsi_result_to_string(tsi_result result) { return "TSI_HANDSHAKE_IN_PROGRESS"; case TSI_OUT_OF_RESOURCES: return "TSI_OUT_OF_RESOURCES"; + case TSI_ASYNC: + return "TSI_ASYNC"; default: return "UNKNOWN"; } @@ -185,11 +187,53 @@ tsi_result tsi_handshaker_create_frame_protector( return result; } +tsi_result tsi_handshaker_next( + tsi_handshaker *self, const unsigned char *received_bytes, + size_t received_bytes_size, unsigned char **bytes_to_send, + size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result, + tsi_handshaker_on_next_done_cb *cb, void *user_data) { + if (self == NULL) return TSI_INVALID_ARGUMENT; + if (self->handshaker_result_created) return TSI_FAILED_PRECONDITION; + return self->vtable->next(self, received_bytes, received_bytes_size, + bytes_to_send, bytes_to_send_size, + handshaker_result, cb, user_data); +} + void tsi_handshaker_destroy(tsi_handshaker *self) { if (self == NULL) return; self->vtable->destroy(self); } +/* --- tsi_handshaker_result implementation. --- */ + +tsi_result tsi_handshaker_result_extract_peer(tsi_handshaker_result *self, + tsi_peer *peer) { + if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT; + memset(peer, 0, sizeof(tsi_peer)); + return self->vtable->extract_peer(self, peer); +} + +tsi_result tsi_handshaker_result_create_frame_protector( + tsi_handshaker_result *self, size_t *max_protected_frame_size, + tsi_frame_protector **protector) { + if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT; + return self->vtable->create_frame_protector(self, max_protected_frame_size, + protector); +} + +tsi_result tsi_handshaker_result_get_unused_bytes( + tsi_handshaker_result *self, unsigned char **bytes, size_t *bytes_size) { + if (self == NULL || bytes == NULL || bytes_size == NULL) { + return TSI_INVALID_ARGUMENT; + } + return self->vtable->get_unused_bytes(self, bytes, bytes_size); +} + +void tsi_handshaker_result_destroy(tsi_handshaker_result *self) { + if (self == NULL) return; + self->vtable->destroy(self); +} + /* --- tsi_peer implementation. --- */ tsi_peer_property tsi_init_peer_property(void) { diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h index 491fa1a8bd6..552ee22061a 100644 --- a/src/core/tsi/transport_security.h +++ b/src/core/tsi/transport_security.h @@ -81,11 +81,33 @@ typedef struct { size_t *max_protected_frame_size, tsi_frame_protector **protector); void (*destroy)(tsi_handshaker *self); + tsi_result (*next)(tsi_handshaker *self, const unsigned char *received_bytes, + size_t received_bytes_size, unsigned char **bytes_to_send, + size_t *bytes_to_send_size, + tsi_handshaker_result **handshaker_result, + tsi_handshaker_on_next_done_cb *cb, void *user_data); } tsi_handshaker_vtable; struct tsi_handshaker { const tsi_handshaker_vtable *vtable; int frame_protector_created; + int handshaker_result_created; +}; + +/* Base for tsi_handshaker_result implementations. + See transport_security_interface.h for documentation. */ +typedef struct { + tsi_result (*extract_peer)(tsi_handshaker_result *self, tsi_peer *peer); + tsi_result (*create_frame_protector)(tsi_handshaker_result *self, + size_t *max_output_protected_frame_size, + tsi_frame_protector **protector); + tsi_result (*get_unused_bytes)(tsi_handshaker_result *self, + unsigned char **bytes, size_t *bytes_size); + void (*destroy)(tsi_handshaker_result *self); +} tsi_handshaker_result_vtable; + +struct tsi_handshaker_result { + const tsi_handshaker_result_vtable *vtable; }; /* Peer and property construction/destruction functions. */ diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c new file mode 100644 index 00000000000..9a7808c09c8 --- /dev/null +++ b/src/core/tsi/transport_security_adapter.c @@ -0,0 +1,230 @@ +/* + * + * 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. + * + */ + +#include "src/core/tsi/transport_security_adapter.h" + +#include + +#include +#include +#include "src/core/tsi/transport_security.h" + +#define TSI_ADAPTER_INITIAL_BUFFER_SIZE 256 + +/* --- tsi_adapter_handshaker_result implementation ---*/ + +typedef struct { + tsi_handshaker_result base; + tsi_handshaker *handshaker; + unsigned char *unused_bytes; + size_t unused_bytes_size; +} tsi_adapter_handshaker_result; + +static tsi_result tsi_adapter_result_extract_peer(tsi_handshaker_result *self, + tsi_peer *peer) { + tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; + return tsi_handshaker_extract_peer(impl->handshaker, peer); +} + +static tsi_result tsi_adapter_result_create_frame_protector( + tsi_handshaker_result *self, size_t *max_output_protected_frame_size, + tsi_frame_protector **protector) { + tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; + return tsi_handshaker_create_frame_protector( + impl->handshaker, max_output_protected_frame_size, protector); +} + +static tsi_result tsi_adapter_result_get_unused_bytes( + tsi_handshaker_result *self, unsigned char **bytes, size_t *byte_size) { + tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; + *bytes = impl->unused_bytes; + *byte_size = impl->unused_bytes_size; + return TSI_OK; +} + +static void tsi_adapter_result_destroy(tsi_handshaker_result *self) { + tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; + if (impl->unused_bytes != NULL) { + gpr_free(impl->unused_bytes); + } + gpr_free(self); +} + +static const tsi_handshaker_result_vtable result_vtable = { + tsi_adapter_result_extract_peer, tsi_adapter_result_create_frame_protector, + tsi_adapter_result_get_unused_bytes, tsi_adapter_result_destroy, +}; + +tsi_result tsi_adapter_create_handshaker_result( + tsi_handshaker *handshaker, const unsigned char *unused_bytes, + size_t unused_bytes_size, tsi_handshaker_result **handshaker_result) { + if (handshaker == NULL || (unused_bytes_size > 0 && unused_bytes == NULL)) { + return TSI_INVALID_ARGUMENT; + } + tsi_adapter_handshaker_result *impl = gpr_zalloc(sizeof(*impl)); + impl->base.vtable = &result_vtable; + impl->handshaker = handshaker; + impl->unused_bytes_size = unused_bytes_size; + if (unused_bytes_size > 0) { + impl->unused_bytes = gpr_malloc(unused_bytes_size); + memcpy(impl->unused_bytes, unused_bytes, unused_bytes_size); + } else { + impl->unused_bytes = NULL; + } + *handshaker_result = &impl->base; + return TSI_OK; +} + +/* --- tsi_adapter_handshaker implementation ---*/ + +typedef struct { + tsi_handshaker base; + tsi_handshaker *wrapped; + unsigned char *adapter_buffer; + size_t adapter_buffer_size; +} tsi_adapter_handshaker; + +tsi_result tsi_adapter_get_bytes_to_send_to_peer(tsi_handshaker *self, + unsigned char *bytes, + size_t *bytes_size) { + return tsi_handshaker_get_bytes_to_send_to_peer( + tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size); +} + +tsi_result tsi_adapter_process_bytes_from_peer(tsi_handshaker *self, + const unsigned char *bytes, + size_t *bytes_size) { + return tsi_handshaker_process_bytes_from_peer( + tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size); +} + +tsi_result tsi_adapter_get_result(tsi_handshaker *self) { + return tsi_handshaker_get_result(tsi_adapter_handshaker_get_wrapped(self)); +} + +tsi_result tsi_adapter_extract_peer(tsi_handshaker *self, tsi_peer *peer) { + return tsi_handshaker_extract_peer(tsi_adapter_handshaker_get_wrapped(self), + peer); +} + +tsi_result tsi_adapter_create_frame_protector(tsi_handshaker *self, + size_t *max_protected_frame_size, + tsi_frame_protector **protector) { + return tsi_handshaker_create_frame_protector( + tsi_adapter_handshaker_get_wrapped(self), max_protected_frame_size, + protector); +} + +void tsi_adapter_destroy(tsi_handshaker *self) { + tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)self; + tsi_handshaker_destroy(impl->wrapped); + gpr_free(impl->adapter_buffer); + gpr_free(self); +} + +tsi_result tsi_adapter_next( + tsi_handshaker *self, const unsigned char *received_bytes, + size_t received_bytes_size, unsigned char **bytes_to_send, + size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result, + tsi_handshaker_on_next_done_cb *cb, void *user_data) { + /* Input sanity check. */ + if ((received_bytes_size > 0 && received_bytes == NULL) || + bytes_to_send == NULL || bytes_to_send_size == NULL || + handshaker_result == NULL) { + return TSI_INVALID_ARGUMENT; + } + + /* If there are received bytes, process them first. */ + tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)self; + tsi_result status = TSI_OK; + size_t bytes_consumed = received_bytes_size; + if (received_bytes_size > 0) { + status = tsi_handshaker_process_bytes_from_peer( + impl->wrapped, received_bytes, &bytes_consumed); + if (status != TSI_OK) return status; + } + + /* Get bytes to send to the peer, if available. */ + size_t offset = 0; + do { + size_t to_send_size = impl->adapter_buffer_size - offset; + status = tsi_handshaker_get_bytes_to_send_to_peer( + impl->wrapped, impl->adapter_buffer + offset, &to_send_size); + offset += to_send_size; + if (status == TSI_INCOMPLETE_DATA) { + impl->adapter_buffer_size *= 2; + impl->adapter_buffer = + gpr_realloc(impl->adapter_buffer, impl->adapter_buffer_size); + } + } while (status == TSI_INCOMPLETE_DATA); + if (status != TSI_OK) return status; + *bytes_to_send = impl->adapter_buffer; + *bytes_to_send_size = offset; + + /* If handshake completes, create tsi_handshaker_result. */ + if (!tsi_handshaker_is_in_progress(impl->wrapped)) { + size_t unused_bytes_size = received_bytes_size - bytes_consumed; + const unsigned char *unused_bytes = + unused_bytes_size == 0 ? NULL : received_bytes + bytes_consumed; + return tsi_adapter_create_handshaker_result( + impl->wrapped, unused_bytes, unused_bytes_size, handshaker_result); + } + *handshaker_result = NULL; + return TSI_OK; +} + +static const tsi_handshaker_vtable handshaker_vtable = { + tsi_adapter_get_bytes_to_send_to_peer, + tsi_adapter_process_bytes_from_peer, + tsi_adapter_get_result, + tsi_adapter_extract_peer, + tsi_adapter_create_frame_protector, + tsi_adapter_destroy, + tsi_adapter_next, +}; + +tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped) { + GPR_ASSERT(wrapped != NULL); + tsi_adapter_handshaker *impl = gpr_zalloc(sizeof(*impl)); + impl->base.vtable = &handshaker_vtable; + impl->wrapped = wrapped; + impl->adapter_buffer_size = TSI_ADAPTER_INITIAL_BUFFER_SIZE; + impl->adapter_buffer = gpr_malloc(impl->adapter_buffer_size); + return &impl->base; +} + +tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter) { + if (adapter == NULL) return NULL; + tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)adapter; + return impl->wrapped; +} diff --git a/src/core/tsi/transport_security_adapter.h b/src/core/tsi/transport_security_adapter.h new file mode 100644 index 00000000000..de5aaefd5f1 --- /dev/null +++ b/src/core/tsi/transport_security_adapter.h @@ -0,0 +1,55 @@ +/* + * + * 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_SRC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H +#define GRPC_SRC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H + +#include "src/core/tsi/transport_security_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create a tsi handshaker that takes an implementation of old interface and + converts into an implementation of new interface. + Ownership of input tsi_handshaker is transferred to this new adapter. */ +tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped); + +/* Given a tsi adapter handshaker, return the original wrapped handshaker. */ +tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter); + +#ifdef __cplusplus +} +#endif + +#endif // GRPC_SRC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index caed43eac44..eaa02bf7f5f 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -56,7 +56,8 @@ typedef enum { TSI_NOT_FOUND = 9, TSI_PROTOCOL_FAILURE = 10, TSI_HANDSHAKE_IN_PROGRESS = 11, - TSI_OUT_OF_RESOURCES = 12 + TSI_OUT_OF_RESOURCES = 12, + TSI_ASYNC = 13 } tsi_result; typedef enum { @@ -208,76 +209,203 @@ typedef struct { /* Destructs the tsi_peer object. */ void tsi_peer_destruct(tsi_peer *self); +/* --- tsi_handshaker_result object --- + + This object contains all necessary handshake results and data such as peer + info, negotiated keys, unused handshake bytes, when the handshake completes. + Implementations of this object must be thread compatible. */ + +typedef struct tsi_handshaker_result tsi_handshaker_result; + +/* This method extracts tsi peer. It returns TSI_OK assuming there is no fatal + error. + The caller is responsible for destructing the peer. */ +tsi_result tsi_handshaker_result_extract_peer(tsi_handshaker_result *self, + tsi_peer *peer); + +/* This method creates a tsi_frame_protector object. It returns TSI_OK assuming + there is no fatal error. + The caller is responsible for destroying the protector. */ +tsi_result tsi_handshaker_result_create_frame_protector( + tsi_handshaker_result *self, size_t *max_output_protected_frame_size, + tsi_frame_protector **protector); + +/* This method returns the unused bytes from the handshake. It returns TSI_OK + assuming there is no fatal error. + The caller should not free the bytes. */ +tsi_result tsi_handshaker_result_get_unused_bytes(tsi_handshaker_result *self, + unsigned char **bytes, + size_t *byte_size); + +/* This method releases the tsi_handshaker_handshaker object. After this method + is called, no other method can be called on the object. */ +void tsi_handshaker_result_destroy(tsi_handshaker_result *self); + /* --- tsi_handshaker objects ---- Implementations of this object must be thread compatible. - A typical usage of this object would be: + ------------------------------------------------------------------------ + + A typical usage of the synchronous TSI handshaker would be: ------------------------------------------------------------------------ - tsi_result result = TSI_OK; + tsi_result status = TSI_OK; unsigned char buf[4096]; - size_t buf_offset; - size_t buf_size; + const size_t buf_size = 4906; + size_t bytes_received_size = 0; + unsigned char *bytes_to_send = NULL; + size_t bytes_to_send_size = 0; + tsi_handshaker_result *result = NULL; + while (1) { - // See if we need to send some bytes to the peer. - do { - size_t buf_size_to_send = sizeof(buf); - result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf, - &buf_size_to_send); - if (buf_size_to_send > 0) send_bytes_to_peer(buf, buf_size_to_send); - } while (result == TSI_INCOMPLETE_DATA); - if (result != TSI_OK) return result; - if (!tsi_handshaker_is_in_progress(handshaker)) break; - - do { - // Read bytes from the peer. - buf_size = sizeof(buf); - buf_offset = 0; - read_bytes_from_peer(buf, &buf_size); - if (buf_size == 0) break; - - // Process the bytes from the peer. We have to be careful as these bytes - // may contain non-handshake data (protected data). If this is the case, - // we will exit from the loop with buf_size > 0. - size_t consumed_by_handshaker = buf_size; - result = tsi_handshaker_process_bytes_from_peer( - handshaker, buf, &consumed_by_handshaker); - buf_size -= consumed_by_handshaker; - buf_offset += consumed_by_handshaker; - } while (result == TSI_INCOMPLETE_DATA); - - if (result != TSI_OK) return result; - if (!tsi_handshaker_is_in_progress(handshaker)) break; + status = tsi_handshaker_next( + handshaker, buf, bytes_received_size, + &bytes_to_send, &bytes_to_send_size, &result, NULL, NULL); + if (status == TSI_INCOMPLETE_DATA) { + // Need more data from the peer. + bytes_received_size = buf_size; + read_bytes_from_peer(buf, &bytes_received_size); + continue; + } + if (status != TSI_OK) return status; + if (bytes_to_send_size > 0) { + send_bytes_to_peer(bytes_to_send, bytes_to_send_size); + } + if (result != NULL) break; + bytes_received_size = buf_size; + read_bytes_from_peer(buf, &bytes_received_size); } // Check the Peer. tsi_peer peer; - do { - result = tsi_handshaker_extract_peer(handshaker, &peer); - if (result != TSI_OK) break; - result = check_peer(&peer); - } while (0); + status = tsi_handshaker_result_extract_peer(result, &peer); + if (status != TSI_OK) return status; + status = check_peer(&peer); tsi_peer_destruct(&peer); - if (result != TSI_OK) return result; + if (status != TSI_OK) return status; // Create the protector. tsi_frame_protector* protector = NULL; - result = tsi_handshaker_create_frame_protector(handshaker, NULL, - &protector); - if (result != TSI_OK) return result; + status = tsi_handshaker_result_create_frame_protector(result, NULL, + &protector); + if (status != TSI_OK) return status; // Do not forget to unprotect outstanding data if any. - if (buf_size > 0) { - result = tsi_frame_protector_unprotect(protector, buf + buf_offset, - buf_size, ..., ...); + unsigned char *unused_bytes = NULL; + size_t unused_bytes_size = 0; + status = tsi_handshaker_result_get_unused_byte(result, &unused_bytes, + &unused_bytes_size); + if (status != TSI_OK) return status; + if (unused_bytes_size > 0) { + status = tsi_frame_protector_unprotect(protector, unused_bytes, + unused_bytes_size, ..., ...); .... } ... + ------------------------------------------------------------------------ + + A typical usage of the new TSI would be as follows, supporting both + synchronous and asynchrnous TSI handshaker implementations: + + ------------------------------------------------------------------------ + + typedef struct { + tsi_handshaker *handshaker; + tsi_handshaker_result *handshaker_result; + unsigned char *handshake_buffer; + size_t handshake_buffer_size; + ... + } security_handshaker; + + void do_handshake(security_handshaker *h, ...) { + // Start the handshake by the calling do_handshake_next. + do_handshake_next(h, NULL, 0); + ... + } + + // This method is a wrapper of the callback function to execute when + // tsi_handshaker_next finishes. It is passed to tsi_handshaker_next as + // the callback function. + void on_handshake_next_done_wrapper( + tsi_result status, void *user_data, const unsigned char *bytes_to_send, + size_t bytes_to_send_size, const tsi_handshaker_result *result) { + security_handshaker *h = (security_handshaker *)user_data; + on_handshake_next_done(h, status, bytes_to_send, + bytes_to_send_size, result); + } + + // This method is the callback function when there are data received from + // the peer. This method will read bytes into the handshake buffer and call + // do_handshake_next. + void on_handshake_data_received_from_peer(void *user_data) { + security_handshaker *h = (security_handshaker *)user_data; + size_t bytes_received_size = h->handshake_buffer_size; + read_bytes_from_peer(h->handshake_buffer, &bytes_received_size); + do_handshake_next(h, h->handshake_buffer, bytes_received_size); + } + + // This method processes a step of handshake, calling tsi_handshaker_next. + void do_handshake_next(security_handshaker *h, + const unsigned char* bytes_received, + size_t bytes_received_size) { + tsi_result status = TSI_OK; + unsigned char *bytes_to_send = NULL; + size_t bytes_to_send_size = 0; + tsi_handshaker_result *result = NULL; + status = tsi_handshaker_next( + handshaker, bytes_received, bytes_received_size, &bytes_to_send, + &bytes_to_send_size, &result, on_handshake_next_done_wrapper, h); + // If TSI handshaker is asynchronous, on_handshake_next_done will be + // called during the execution of the callback function. + if (status == TSI_ASYNC) return; + on_handshake_next_done(h, status, bytes_to_send, + bytes_to_send_size, result); + } + + // This is the real function to execute after tsi_handshaker_next. + void on_handshake_next_done( + security_handshaker *h, tsi_result status, + const unsigned char *bytes_to_send, size_t bytes_to_send_size, + const tsi_handshaker_result *result) { + if (status == TSI_INCOMPLETE_DATA) { + // Schedule an asynchronous read from the peer. If handshake data are + // received, on_handshake_data_received_from_peer will be called. + async_read_from_peer(..., ..., on_handshake_data_received_from_peer); + return; + } + if (status != TSI_OK) return; + + if (bytes_to_send_size > 0) { + send_bytes_to_peer(bytes_to_send, bytes_to_send_size); + } + + if (result != NULL) { + // Handshake completed. + h->result = result; + // Check the Peer. + tsi_peer peer; + status = tsi_handshaker_result_extract_peer(result, &peer); + if (status != TSI_OK) return status; + status = check_peer(&peer); + tsi_peer_destruct(&peer); + if (status != TSI_OK) return; + + // Create the protector. + tsi_frame_protector* protector = NULL; + status = tsi_handshaker_result_create_frame_protector(result, NULL, + &protector); + if (status != TSI_OK) return; + + // Do not forget to unprotect outstanding data if any. + .... + } + } ------------------------------------------------------------------------ */ typedef struct tsi_handshaker tsi_handshaker; -/* Gets bytes that need to be sent to the peer. +/* TO BE DEPRECATED SOON. + Gets bytes that need to be sent to the peer. - bytes is the buffer that will be written with the data to be sent to the peer. - bytes_size is an input/output parameter specifying the capacity of the @@ -292,7 +420,8 @@ tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size); -/* Processes bytes received from the peer. +/* TO BE DEPRECATED SOON. + Processes bytes received from the peer. - bytes is the buffer containing the data. - bytes_size is an input/output parameter specifying the size of the data as input and the number of bytes consumed as output. @@ -305,24 +434,28 @@ tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size); -/* Gets the result of the handshaker. +/* TO BE DEPRECATED SOON. + Gets the result of the handshaker. Returns TSI_OK if the hanshake completed successfully and there has been no errors. Returns TSI_HANDSHAKE_IN_PROGRESS if the handshaker is not done yet but no error has been encountered so far. Otherwise the handshaker failed with the returned error. */ tsi_result tsi_handshaker_get_result(tsi_handshaker *self); -/* Returns 1 if the handshake is in progress, 0 otherwise. */ +/* TO BE DEPRECATED SOON. + Returns 1 if the handshake is in progress, 0 otherwise. */ #define tsi_handshaker_is_in_progress(h) \ (tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS) -/* This method may return TSI_FAILED_PRECONDITION if +/* TO BE DEPRECATED SOON. + This method may return TSI_FAILED_PRECONDITION if tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise assuming the handshaker is not in a fatal error state. The caller is responsible for destructing the peer. */ tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer); -/* This method creates a tsi_frame_protector object after the handshake phase +/* TO BE DEPRECATED SOON. + This method creates a tsi_frame_protector object after the handshake phase is done. After this method has been called successfully, the only method that can be called on this object is Destroy. - max_output_protected_frame_size is an input/output parameter specifying the @@ -342,10 +475,52 @@ tsi_result tsi_handshaker_create_frame_protector( tsi_handshaker *self, size_t *max_output_protected_frame_size, tsi_frame_protector **protector); +/* Callback function definition for tsi_handshaker_next. + - status indicates the status of the next operation. + - user_data is the argument to callback function passed from the caller. + - bytes_to_send is the data buffer to be sent to the peer. + - bytes_to_send_size is the size of data buffer to be sent to the peer. + - handshaker_result is the result of handshake when the handshake completes, + is NULL otherwise. */ +typedef void (*tsi_handshaker_on_next_done_cb)( + tsi_result status, void *user_data, const unsigned char *bytes_to_send, + size_t bytes_to_send_size, const tsi_handshaker_result *handshaker_result); + +/* Conduct a next step of the handshake. + - received_bytes is the buffer containing the data received from the peer. + - received_bytes_size is the size of the data received from the peer. + - bytes_to_send is the data buffer to be sent to the peer. + - bytes_to_send_size is the size of data buffer to be sent to the peer. + - handshaker_result is the result of handshake if the handshake completes. + - cb is the callback function defined above. It can be NULL for synchronous + TSI handshaker implementation. + - user_data is the argument to callback function passed from the caller. + This method returns TSI_ASYNC if the TSI handshaker implementation is + asynchronous. It returns TSI_OK if the handshake completes or if there are + data to send to the peer, otherwise returns TSI_INCOMPLETE_DATA which + indicates that this method needs to be called again with more data from the + peer. In case of a fatal error in the handshake, another specific error code + is returned. + The caller is responsible for destroying the handshaker_result. However, the + caller should not free bytes_to_send, as the buffer is owned by the + tsi_handshaker object. */ +tsi_result tsi_handshaker_next( + tsi_handshaker *self, const unsigned char *received_bytes, + size_t received_bytes_size, unsigned char **bytes_to_send, + size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result, + tsi_handshaker_on_next_done_cb *cb, void *user_data); + /* This method releases the tsi_handshaker object. After this method is called, no other method can be called on the object. */ void tsi_handshaker_destroy(tsi_handshaker *self); +/* This method initializes the necessary shared objects used for tsi + implementation. */ +void tsi_init(); + +/* This method destroys the shared objects created by tsi_init. */ +void tsi_destroy(); + #ifdef __cplusplus } #endif diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c index ee4a37c3141..4214407823a 100644 --- a/test/core/tsi/transport_security_test.c +++ b/test/core/tsi/transport_security_test.c @@ -376,6 +376,8 @@ static void test_handshaker_invalid_args(void) { TSI_INVALID_ARGUMENT); GPR_ASSERT(tsi_handshaker_get_bytes_to_send_to_peer(NULL, NULL, NULL) == TSI_INVALID_ARGUMENT); + GPR_ASSERT(tsi_handshaker_next(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL) == + TSI_INVALID_ARGUMENT); } static void test_handshaker_invalid_state(void) { From 20b9f9432836b8959c034a01c51325d9c3b7c00a Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Fri, 7 Apr 2017 12:50:33 -0700 Subject: [PATCH 02/21] Update TSI with new non-blocking TSI interfaces. --- Makefile | 3 + src/core/tsi/fake_transport_security.c | 1 + src/core/tsi/ssl_transport_security.c | 1 + src/core/tsi/transport_security.c | 44 +++ src/core/tsi/transport_security.h | 22 ++ src/core/tsi/transport_security_adapter.c | 230 ++++++++++++++++ src/core/tsi/transport_security_adapter.h | 55 ++++ src/core/tsi/transport_security_interface.h | 279 ++++++++++++++++---- test/core/tsi/transport_security_test.c | 2 + 9 files changed, 585 insertions(+), 52 deletions(-) create mode 100644 src/core/tsi/transport_security_adapter.c create mode 100644 src/core/tsi/transport_security_adapter.h diff --git a/Makefile b/Makefile index 91a74f354e8..cbf38709911 100644 --- a/Makefile +++ b/Makefile @@ -2987,6 +2987,7 @@ LIBGRPC_SRC = \ src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ + src/core/tsi/transport_security_adapter.c \ src/core/ext/transport/chttp2/server/chttp2_server.c \ src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \ src/core/ext/filters/client_channel/channel_connectivity.c \ @@ -3330,6 +3331,7 @@ LIBGRPC_CRONET_SRC = \ src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ + src/core/tsi/transport_security_adapter.c \ src/core/ext/transport/chttp2/client/chttp2_connector.c \ src/core/ext/filters/load_reporting/load_reporting.c \ src/core/ext/filters/load_reporting/load_reporting_filter.c \ @@ -19257,6 +19259,7 @@ src/core/plugin_registry/grpc_plugin_registry.c: $(OPENSSL_DEP) src/core/tsi/fake_transport_security.c: $(OPENSSL_DEP) src/core/tsi/ssl_transport_security.c: $(OPENSSL_DEP) src/core/tsi/transport_security.c: $(OPENSSL_DEP) +src/core/tsi/transport_security_adapter.c: $(OPENSSL_DEP) src/cpp/client/cronet_credentials.cc: $(OPENSSL_DEP) src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP) src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP) diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c index 822fad51cb3..1836beefc42 100644 --- a/src/core/tsi/fake_transport_security.c +++ b/src/core/tsi/fake_transport_security.c @@ -499,6 +499,7 @@ static const tsi_handshaker_vtable handshaker_vtable = { fake_handshaker_extract_peer, fake_handshaker_create_frame_protector, fake_handshaker_destroy, + NULL, }; tsi_handshaker *tsi_create_fake_handshaker(int is_client) { diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index a0325cc1835..c4dba002f8b 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -1049,6 +1049,7 @@ static const tsi_handshaker_vtable handshaker_vtable = { ssl_handshaker_extract_peer, ssl_handshaker_create_frame_protector, ssl_handshaker_destroy, + NULL, }; /* --- tsi_ssl_handshaker_factory common methods. --- */ diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c index 67ebe1b1f30..a9cb6a107ca 100644 --- a/src/core/tsi/transport_security.c +++ b/src/core/tsi/transport_security.c @@ -73,6 +73,8 @@ const char *tsi_result_to_string(tsi_result result) { return "TSI_HANDSHAKE_IN_PROGRESS"; case TSI_OUT_OF_RESOURCES: return "TSI_OUT_OF_RESOURCES"; + case TSI_ASYNC: + return "TSI_ASYNC"; default: return "UNKNOWN"; } @@ -185,11 +187,53 @@ tsi_result tsi_handshaker_create_frame_protector( return result; } +tsi_result tsi_handshaker_next( + tsi_handshaker *self, const unsigned char *received_bytes, + size_t received_bytes_size, unsigned char **bytes_to_send, + size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result, + tsi_handshaker_on_next_done_cb cb, void *user_data) { + if (self == NULL) return TSI_INVALID_ARGUMENT; + if (self->handshaker_result_created) return TSI_FAILED_PRECONDITION; + return self->vtable->next(self, received_bytes, received_bytes_size, + bytes_to_send, bytes_to_send_size, + handshaker_result, cb, user_data); +} + void tsi_handshaker_destroy(tsi_handshaker *self) { if (self == NULL) return; self->vtable->destroy(self); } +/* --- tsi_handshaker_result implementation. --- */ + +tsi_result tsi_handshaker_result_extract_peer(tsi_handshaker_result *self, + tsi_peer *peer) { + if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT; + memset(peer, 0, sizeof(tsi_peer)); + return self->vtable->extract_peer(self, peer); +} + +tsi_result tsi_handshaker_result_create_frame_protector( + tsi_handshaker_result *self, size_t *max_protected_frame_size, + tsi_frame_protector **protector) { + if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT; + return self->vtable->create_frame_protector(self, max_protected_frame_size, + protector); +} + +tsi_result tsi_handshaker_result_get_unused_bytes( + tsi_handshaker_result *self, unsigned char **bytes, size_t *bytes_size) { + if (self == NULL || bytes == NULL || bytes_size == NULL) { + return TSI_INVALID_ARGUMENT; + } + return self->vtable->get_unused_bytes(self, bytes, bytes_size); +} + +void tsi_handshaker_result_destroy(tsi_handshaker_result *self) { + if (self == NULL) return; + self->vtable->destroy(self); +} + /* --- tsi_peer implementation. --- */ tsi_peer_property tsi_init_peer_property(void) { diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h index 491fa1a8bd6..2e821108279 100644 --- a/src/core/tsi/transport_security.h +++ b/src/core/tsi/transport_security.h @@ -81,11 +81,33 @@ typedef struct { size_t *max_protected_frame_size, tsi_frame_protector **protector); void (*destroy)(tsi_handshaker *self); + tsi_result (*next)(tsi_handshaker *self, const unsigned char *received_bytes, + size_t received_bytes_size, unsigned char **bytes_to_send, + size_t *bytes_to_send_size, + tsi_handshaker_result **handshaker_result, + tsi_handshaker_on_next_done_cb cb, void *user_data); } tsi_handshaker_vtable; struct tsi_handshaker { const tsi_handshaker_vtable *vtable; int frame_protector_created; + int handshaker_result_created; +}; + +/* Base for tsi_handshaker_result implementations. + See transport_security_interface.h for documentation. */ +typedef struct { + tsi_result (*extract_peer)(tsi_handshaker_result *self, tsi_peer *peer); + tsi_result (*create_frame_protector)(tsi_handshaker_result *self, + size_t *max_output_protected_frame_size, + tsi_frame_protector **protector); + tsi_result (*get_unused_bytes)(tsi_handshaker_result *self, + unsigned char **bytes, size_t *bytes_size); + void (*destroy)(tsi_handshaker_result *self); +} tsi_handshaker_result_vtable; + +struct tsi_handshaker_result { + const tsi_handshaker_result_vtable *vtable; }; /* Peer and property construction/destruction functions. */ diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c new file mode 100644 index 00000000000..7e0b8f574a0 --- /dev/null +++ b/src/core/tsi/transport_security_adapter.c @@ -0,0 +1,230 @@ +/* + * + * 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. + * + */ + +#include "src/core/tsi/transport_security_adapter.h" + +#include + +#include +#include +#include "src/core/tsi/transport_security.h" + +#define TSI_ADAPTER_INITIAL_BUFFER_SIZE 256 + +/* --- tsi_adapter_handshaker_result implementation ---*/ + +typedef struct { + tsi_handshaker_result base; + tsi_handshaker *handshaker; + unsigned char *unused_bytes; + size_t unused_bytes_size; +} tsi_adapter_handshaker_result; + +static tsi_result tsi_adapter_result_extract_peer(tsi_handshaker_result *self, + tsi_peer *peer) { + tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; + return tsi_handshaker_extract_peer(impl->handshaker, peer); +} + +static tsi_result tsi_adapter_result_create_frame_protector( + tsi_handshaker_result *self, size_t *max_output_protected_frame_size, + tsi_frame_protector **protector) { + tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; + return tsi_handshaker_create_frame_protector( + impl->handshaker, max_output_protected_frame_size, protector); +} + +static tsi_result tsi_adapter_result_get_unused_bytes( + tsi_handshaker_result *self, unsigned char **bytes, size_t *byte_size) { + tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; + *bytes = impl->unused_bytes; + *byte_size = impl->unused_bytes_size; + return TSI_OK; +} + +static void tsi_adapter_result_destroy(tsi_handshaker_result *self) { + tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; + if (impl->unused_bytes != NULL) { + gpr_free(impl->unused_bytes); + } + gpr_free(self); +} + +static const tsi_handshaker_result_vtable result_vtable = { + tsi_adapter_result_extract_peer, tsi_adapter_result_create_frame_protector, + tsi_adapter_result_get_unused_bytes, tsi_adapter_result_destroy, +}; + +tsi_result tsi_adapter_create_handshaker_result( + tsi_handshaker *handshaker, const unsigned char *unused_bytes, + size_t unused_bytes_size, tsi_handshaker_result **handshaker_result) { + if (handshaker == NULL || (unused_bytes_size > 0 && unused_bytes == NULL)) { + return TSI_INVALID_ARGUMENT; + } + tsi_adapter_handshaker_result *impl = gpr_zalloc(sizeof(*impl)); + impl->base.vtable = &result_vtable; + impl->handshaker = handshaker; + impl->unused_bytes_size = unused_bytes_size; + if (unused_bytes_size > 0) { + impl->unused_bytes = gpr_malloc(unused_bytes_size); + memcpy(impl->unused_bytes, unused_bytes, unused_bytes_size); + } else { + impl->unused_bytes = NULL; + } + *handshaker_result = &impl->base; + return TSI_OK; +} + +/* --- tsi_adapter_handshaker implementation ---*/ + +typedef struct { + tsi_handshaker base; + tsi_handshaker *wrapped; + unsigned char *adapter_buffer; + size_t adapter_buffer_size; +} tsi_adapter_handshaker; + +tsi_result tsi_adapter_get_bytes_to_send_to_peer(tsi_handshaker *self, + unsigned char *bytes, + size_t *bytes_size) { + return tsi_handshaker_get_bytes_to_send_to_peer( + tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size); +} + +tsi_result tsi_adapter_process_bytes_from_peer(tsi_handshaker *self, + const unsigned char *bytes, + size_t *bytes_size) { + return tsi_handshaker_process_bytes_from_peer( + tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size); +} + +tsi_result tsi_adapter_get_result(tsi_handshaker *self) { + return tsi_handshaker_get_result(tsi_adapter_handshaker_get_wrapped(self)); +} + +tsi_result tsi_adapter_extract_peer(tsi_handshaker *self, tsi_peer *peer) { + return tsi_handshaker_extract_peer(tsi_adapter_handshaker_get_wrapped(self), + peer); +} + +tsi_result tsi_adapter_create_frame_protector(tsi_handshaker *self, + size_t *max_protected_frame_size, + tsi_frame_protector **protector) { + return tsi_handshaker_create_frame_protector( + tsi_adapter_handshaker_get_wrapped(self), max_protected_frame_size, + protector); +} + +void tsi_adapter_destroy(tsi_handshaker *self) { + tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)self; + tsi_handshaker_destroy(impl->wrapped); + gpr_free(impl->adapter_buffer); + gpr_free(self); +} + +tsi_result tsi_adapter_next( + tsi_handshaker *self, const unsigned char *received_bytes, + size_t received_bytes_size, unsigned char **bytes_to_send, + size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result, + tsi_handshaker_on_next_done_cb cb, void *user_data) { + /* Input sanity check. */ + if ((received_bytes_size > 0 && received_bytes == NULL) || + bytes_to_send == NULL || bytes_to_send_size == NULL || + handshaker_result == NULL) { + return TSI_INVALID_ARGUMENT; + } + + /* If there are received bytes, process them first. */ + tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)self; + tsi_result status = TSI_OK; + size_t bytes_consumed = received_bytes_size; + if (received_bytes_size > 0) { + status = tsi_handshaker_process_bytes_from_peer( + impl->wrapped, received_bytes, &bytes_consumed); + if (status != TSI_OK) return status; + } + + /* Get bytes to send to the peer, if available. */ + size_t offset = 0; + do { + size_t to_send_size = impl->adapter_buffer_size - offset; + status = tsi_handshaker_get_bytes_to_send_to_peer( + impl->wrapped, impl->adapter_buffer + offset, &to_send_size); + offset += to_send_size; + if (status == TSI_INCOMPLETE_DATA) { + impl->adapter_buffer_size *= 2; + impl->adapter_buffer = + gpr_realloc(impl->adapter_buffer, impl->adapter_buffer_size); + } + } while (status == TSI_INCOMPLETE_DATA); + if (status != TSI_OK) return status; + *bytes_to_send = impl->adapter_buffer; + *bytes_to_send_size = offset; + + /* If handshake completes, create tsi_handshaker_result. */ + if (!tsi_handshaker_is_in_progress(impl->wrapped)) { + size_t unused_bytes_size = received_bytes_size - bytes_consumed; + const unsigned char *unused_bytes = + unused_bytes_size == 0 ? NULL : received_bytes + bytes_consumed; + return tsi_adapter_create_handshaker_result( + impl->wrapped, unused_bytes, unused_bytes_size, handshaker_result); + } + *handshaker_result = NULL; + return TSI_OK; +} + +static const tsi_handshaker_vtable handshaker_vtable = { + tsi_adapter_get_bytes_to_send_to_peer, + tsi_adapter_process_bytes_from_peer, + tsi_adapter_get_result, + tsi_adapter_extract_peer, + tsi_adapter_create_frame_protector, + tsi_adapter_destroy, + tsi_adapter_next, +}; + +tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped) { + GPR_ASSERT(wrapped != NULL); + tsi_adapter_handshaker *impl = gpr_zalloc(sizeof(*impl)); + impl->base.vtable = &handshaker_vtable; + impl->wrapped = wrapped; + impl->adapter_buffer_size = TSI_ADAPTER_INITIAL_BUFFER_SIZE; + impl->adapter_buffer = gpr_malloc(impl->adapter_buffer_size); + return &impl->base; +} + +tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter) { + if (adapter == NULL) return NULL; + tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)adapter; + return impl->wrapped; +} diff --git a/src/core/tsi/transport_security_adapter.h b/src/core/tsi/transport_security_adapter.h new file mode 100644 index 00000000000..de5aaefd5f1 --- /dev/null +++ b/src/core/tsi/transport_security_adapter.h @@ -0,0 +1,55 @@ +/* + * + * 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_SRC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H +#define GRPC_SRC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H + +#include "src/core/tsi/transport_security_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create a tsi handshaker that takes an implementation of old interface and + converts into an implementation of new interface. + Ownership of input tsi_handshaker is transferred to this new adapter. */ +tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped); + +/* Given a tsi adapter handshaker, return the original wrapped handshaker. */ +tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter); + +#ifdef __cplusplus +} +#endif + +#endif // GRPC_SRC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index caed43eac44..be04810e24f 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -56,7 +56,8 @@ typedef enum { TSI_NOT_FOUND = 9, TSI_PROTOCOL_FAILURE = 10, TSI_HANDSHAKE_IN_PROGRESS = 11, - TSI_OUT_OF_RESOURCES = 12 + TSI_OUT_OF_RESOURCES = 12, + TSI_ASYNC = 13 } tsi_result; typedef enum { @@ -208,76 +209,203 @@ typedef struct { /* Destructs the tsi_peer object. */ void tsi_peer_destruct(tsi_peer *self); +/* --- tsi_handshaker_result object --- + + This object contains all necessary handshake results and data such as peer + info, negotiated keys, unused handshake bytes, when the handshake completes. + Implementations of this object must be thread compatible. */ + +typedef struct tsi_handshaker_result tsi_handshaker_result; + +/* This method extracts tsi peer. It returns TSI_OK assuming there is no fatal + error. + The caller is responsible for destructing the peer. */ +tsi_result tsi_handshaker_result_extract_peer(tsi_handshaker_result *self, + tsi_peer *peer); + +/* This method creates a tsi_frame_protector object. It returns TSI_OK assuming + there is no fatal error. + The caller is responsible for destroying the protector. */ +tsi_result tsi_handshaker_result_create_frame_protector( + tsi_handshaker_result *self, size_t *max_output_protected_frame_size, + tsi_frame_protector **protector); + +/* This method returns the unused bytes from the handshake. It returns TSI_OK + assuming there is no fatal error. + The caller should not free the bytes. */ +tsi_result tsi_handshaker_result_get_unused_bytes(tsi_handshaker_result *self, + unsigned char **bytes, + size_t *byte_size); + +/* This method releases the tsi_handshaker_handshaker object. After this method + is called, no other method can be called on the object. */ +void tsi_handshaker_result_destroy(tsi_handshaker_result *self); + /* --- tsi_handshaker objects ---- Implementations of this object must be thread compatible. - A typical usage of this object would be: + ------------------------------------------------------------------------ + + A typical usage of the synchronous TSI handshaker would be: ------------------------------------------------------------------------ - tsi_result result = TSI_OK; + tsi_result status = TSI_OK; unsigned char buf[4096]; - size_t buf_offset; - size_t buf_size; + const size_t buf_size = 4906; + size_t bytes_received_size = 0; + unsigned char *bytes_to_send = NULL; + size_t bytes_to_send_size = 0; + tsi_handshaker_result *result = NULL; + while (1) { - // See if we need to send some bytes to the peer. - do { - size_t buf_size_to_send = sizeof(buf); - result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf, - &buf_size_to_send); - if (buf_size_to_send > 0) send_bytes_to_peer(buf, buf_size_to_send); - } while (result == TSI_INCOMPLETE_DATA); - if (result != TSI_OK) return result; - if (!tsi_handshaker_is_in_progress(handshaker)) break; - - do { - // Read bytes from the peer. - buf_size = sizeof(buf); - buf_offset = 0; - read_bytes_from_peer(buf, &buf_size); - if (buf_size == 0) break; - - // Process the bytes from the peer. We have to be careful as these bytes - // may contain non-handshake data (protected data). If this is the case, - // we will exit from the loop with buf_size > 0. - size_t consumed_by_handshaker = buf_size; - result = tsi_handshaker_process_bytes_from_peer( - handshaker, buf, &consumed_by_handshaker); - buf_size -= consumed_by_handshaker; - buf_offset += consumed_by_handshaker; - } while (result == TSI_INCOMPLETE_DATA); - - if (result != TSI_OK) return result; - if (!tsi_handshaker_is_in_progress(handshaker)) break; + status = tsi_handshaker_next( + handshaker, buf, bytes_received_size, + &bytes_to_send, &bytes_to_send_size, &result, NULL, NULL); + if (status == TSI_INCOMPLETE_DATA) { + // Need more data from the peer. + bytes_received_size = buf_size; + read_bytes_from_peer(buf, &bytes_received_size); + continue; + } + if (status != TSI_OK) return status; + if (bytes_to_send_size > 0) { + send_bytes_to_peer(bytes_to_send, bytes_to_send_size); + } + if (result != NULL) break; + bytes_received_size = buf_size; + read_bytes_from_peer(buf, &bytes_received_size); } // Check the Peer. tsi_peer peer; - do { - result = tsi_handshaker_extract_peer(handshaker, &peer); - if (result != TSI_OK) break; - result = check_peer(&peer); - } while (0); + status = tsi_handshaker_result_extract_peer(result, &peer); + if (status != TSI_OK) return status; + status = check_peer(&peer); tsi_peer_destruct(&peer); - if (result != TSI_OK) return result; + if (status != TSI_OK) return status; // Create the protector. tsi_frame_protector* protector = NULL; - result = tsi_handshaker_create_frame_protector(handshaker, NULL, - &protector); - if (result != TSI_OK) return result; + status = tsi_handshaker_result_create_frame_protector(result, NULL, + &protector); + if (status != TSI_OK) return status; // Do not forget to unprotect outstanding data if any. - if (buf_size > 0) { - result = tsi_frame_protector_unprotect(protector, buf + buf_offset, - buf_size, ..., ...); + unsigned char *unused_bytes = NULL; + size_t unused_bytes_size = 0; + status = tsi_handshaker_result_get_unused_bytes(result, &unused_bytes, + &unused_bytes_size); + if (status != TSI_OK) return status; + if (unused_bytes_size > 0) { + status = tsi_frame_protector_unprotect(protector, unused_bytes, + unused_bytes_size, ..., ...); .... } ... + ------------------------------------------------------------------------ + + A typical usage of the new TSI would be as follows, supporting both + synchronous and asynchrnous TSI handshaker implementations: + + ------------------------------------------------------------------------ + + typedef struct { + tsi_handshaker *handshaker; + tsi_handshaker_result *handshaker_result; + unsigned char *handshake_buffer; + size_t handshake_buffer_size; + ... + } security_handshaker; + + void do_handshake(security_handshaker *h, ...) { + // Start the handshake by the calling do_handshake_next. + do_handshake_next(h, NULL, 0); + ... + } + + // This method is a wrapper of the callback function to execute when + // tsi_handshaker_next finishes. It is passed to tsi_handshaker_next as + // the callback function. + void on_handshake_next_done_wrapper( + tsi_result status, void *user_data, const unsigned char *bytes_to_send, + size_t bytes_to_send_size, tsi_handshaker_result *result) { + security_handshaker *h = (security_handshaker *)user_data; + on_handshake_next_done(h, status, bytes_to_send, + bytes_to_send_size, result); + } + + // This method is the callback function when there are data received from + // the peer. This method will read bytes into the handshake buffer and call + // do_handshake_next. + void on_handshake_data_received_from_peer(void *user_data) { + security_handshaker *h = (security_handshaker *)user_data; + size_t bytes_received_size = h->handshake_buffer_size; + read_bytes_from_peer(h->handshake_buffer, &bytes_received_size); + do_handshake_next(h, h->handshake_buffer, bytes_received_size); + } + + // This method processes a step of handshake, calling tsi_handshaker_next. + void do_handshake_next(security_handshaker *h, + const unsigned char* bytes_received, + size_t bytes_received_size) { + tsi_result status = TSI_OK; + unsigned char *bytes_to_send = NULL; + size_t bytes_to_send_size = 0; + tsi_handshaker_result *result = NULL; + status = tsi_handshaker_next( + handshaker, bytes_received, bytes_received_size, &bytes_to_send, + &bytes_to_send_size, &result, on_handshake_next_done_wrapper, h); + // If TSI handshaker is asynchronous, on_handshake_next_done will be + // called during the execution of the callback function. + if (status == TSI_ASYNC) return; + on_handshake_next_done(h, status, bytes_to_send, + bytes_to_send_size, result); + } + + // This is the real function to execute after tsi_handshaker_next. + void on_handshake_next_done( + security_handshaker *h, tsi_result status, + const unsigned char *bytes_to_send, size_t bytes_to_send_size, + tsi_handshaker_result *result) { + if (status == TSI_INCOMPLETE_DATA) { + // Schedule an asynchronous read from the peer. If handshake data are + // received, on_handshake_data_received_from_peer will be called. + async_read_from_peer(..., ..., on_handshake_data_received_from_peer); + return; + } + if (status != TSI_OK) return; + + if (bytes_to_send_size > 0) { + send_bytes_to_peer(bytes_to_send, bytes_to_send_size); + } + + if (result != NULL) { + // Handshake completed. + h->result = result; + // Check the Peer. + tsi_peer peer; + status = tsi_handshaker_result_extract_peer(result, &peer); + if (status != TSI_OK) return status; + status = check_peer(&peer); + tsi_peer_destruct(&peer); + if (status != TSI_OK) return; + + // Create the protector. + tsi_frame_protector* protector = NULL; + status = tsi_handshaker_result_create_frame_protector(result, NULL, + &protector); + if (status != TSI_OK) return; + + // Do not forget to unprotect outstanding data if any. + .... + } + } ------------------------------------------------------------------------ */ typedef struct tsi_handshaker tsi_handshaker; -/* Gets bytes that need to be sent to the peer. +/* TO BE DEPRECATED SOON. + Gets bytes that need to be sent to the peer. - bytes is the buffer that will be written with the data to be sent to the peer. - bytes_size is an input/output parameter specifying the capacity of the @@ -292,7 +420,8 @@ tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size); -/* Processes bytes received from the peer. +/* TO BE DEPRECATED SOON. + Processes bytes received from the peer. - bytes is the buffer containing the data. - bytes_size is an input/output parameter specifying the size of the data as input and the number of bytes consumed as output. @@ -305,24 +434,28 @@ tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size); -/* Gets the result of the handshaker. +/* TO BE DEPRECATED SOON. + Gets the result of the handshaker. Returns TSI_OK if the hanshake completed successfully and there has been no errors. Returns TSI_HANDSHAKE_IN_PROGRESS if the handshaker is not done yet but no error has been encountered so far. Otherwise the handshaker failed with the returned error. */ tsi_result tsi_handshaker_get_result(tsi_handshaker *self); -/* Returns 1 if the handshake is in progress, 0 otherwise. */ +/* TO BE DEPRECATED SOON. + Returns 1 if the handshake is in progress, 0 otherwise. */ #define tsi_handshaker_is_in_progress(h) \ (tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS) -/* This method may return TSI_FAILED_PRECONDITION if +/* TO BE DEPRECATED SOON. + This method may return TSI_FAILED_PRECONDITION if tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise assuming the handshaker is not in a fatal error state. The caller is responsible for destructing the peer. */ tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer); -/* This method creates a tsi_frame_protector object after the handshake phase +/* TO BE DEPRECATED SOON. + This method creates a tsi_frame_protector object after the handshake phase is done. After this method has been called successfully, the only method that can be called on this object is Destroy. - max_output_protected_frame_size is an input/output parameter specifying the @@ -342,10 +475,52 @@ tsi_result tsi_handshaker_create_frame_protector( tsi_handshaker *self, size_t *max_output_protected_frame_size, tsi_frame_protector **protector); +/* Callback function definition for tsi_handshaker_next. + - status indicates the status of the next operation. + - user_data is the argument to callback function passed from the caller. + - bytes_to_send is the data buffer to be sent to the peer. + - bytes_to_send_size is the size of data buffer to be sent to the peer. + - handshaker_result is the result of handshake when the handshake completes, + is NULL otherwise. */ +typedef void (*tsi_handshaker_on_next_done_cb)( + tsi_result status, void *user_data, const unsigned char *bytes_to_send, + size_t bytes_to_send_size, tsi_handshaker_result *handshaker_result); + +/* Conduct a next step of the handshake. + - received_bytes is the buffer containing the data received from the peer. + - received_bytes_size is the size of the data received from the peer. + - bytes_to_send is the data buffer to be sent to the peer. + - bytes_to_send_size is the size of data buffer to be sent to the peer. + - handshaker_result is the result of handshake if the handshake completes. + - cb is the callback function defined above. It can be NULL for synchronous + TSI handshaker implementation. + - user_data is the argument to callback function passed from the caller. + This method returns TSI_ASYNC if the TSI handshaker implementation is + asynchronous. It returns TSI_OK if the handshake completes or if there are + data to send to the peer, otherwise returns TSI_INCOMPLETE_DATA which + indicates that this method needs to be called again with more data from the + peer. In case of a fatal error in the handshake, another specific error code + is returned. + The caller is responsible for destroying the handshaker_result. However, the + caller should not free bytes_to_send, as the buffer is owned by the + tsi_handshaker object. */ +tsi_result tsi_handshaker_next( + tsi_handshaker *self, const unsigned char *received_bytes, + size_t received_bytes_size, unsigned char **bytes_to_send, + size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result, + tsi_handshaker_on_next_done_cb cb, void *user_data); + /* This method releases the tsi_handshaker object. After this method is called, no other method can be called on the object. */ void tsi_handshaker_destroy(tsi_handshaker *self); +/* This method initializes the necessary shared objects used for tsi + implementation. */ +void tsi_init(); + +/* This method destroys the shared objects created by tsi_init. */ +void tsi_destroy(); + #ifdef __cplusplus } #endif diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c index ee4a37c3141..4214407823a 100644 --- a/test/core/tsi/transport_security_test.c +++ b/test/core/tsi/transport_security_test.c @@ -376,6 +376,8 @@ static void test_handshaker_invalid_args(void) { TSI_INVALID_ARGUMENT); GPR_ASSERT(tsi_handshaker_get_bytes_to_send_to_peer(NULL, NULL, NULL) == TSI_INVALID_ARGUMENT); + GPR_ASSERT(tsi_handshaker_next(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL) == + TSI_INVALID_ARGUMENT); } static void test_handshaker_invalid_state(void) { From 7400d1ce7548328d0107cea3ebe4dd0488bfe642 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 7 Apr 2017 10:17:40 -0700 Subject: [PATCH 03/21] Ignore a couple of errors in the Node express benchmark --- .../performance/benchmark_client_express.js | 25 +++++++++++++------ .../performance/benchmark_server_express.js | 4 +-- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/node/performance/benchmark_client_express.js b/src/node/performance/benchmark_client_express.js index 675eb5f2884..e749956599d 100644 --- a/src/node/performance/benchmark_client_express.js +++ b/src/node/performance/benchmark_client_express.js @@ -93,7 +93,7 @@ function BenchmarkClient(server_targets, channels, histogram_params, for (var i = 0; i < channels; i++) { var host_port; - host_port = server_targets[i % server_targets.length].split(':') + host_port = server_targets[i % server_targets.length].split(':'); var new_options = _.assign({hostname: host_port[0], port: +host_port[1]}, options); new_options.agent = new protocol.Agent(new_options); this.client_options[i] = new_options; @@ -149,6 +149,17 @@ BenchmarkClient.prototype.startClosedLoop = function( if (self.running) { self.pending_calls++; var start_time = process.hrtime(); + function finishCall(success) { + if (success) { + var time_diff = process.hrtime(start_time); + self.histogram.add(timeDiffToNanos(time_diff)); + } + makeCall(client_options); + self.pending_calls--; + if ((!self.running) && self.pending_calls == 0) { + self.emit('finished'); + } + } var req = self.request(client_options, function(res) { var res_data = ''; res.on('data', function(data) { @@ -156,18 +167,16 @@ BenchmarkClient.prototype.startClosedLoop = function( }); res.on('end', function() { JSON.parse(res_data); - var time_diff = process.hrtime(start_time); - self.histogram.add(timeDiffToNanos(time_diff)); - makeCall(client_options); - self.pending_calls--; - if ((!self.running) && self.pending_calls == 0) { - self.emit('finished'); - } + finishCall(true); }); }); req.write(JSON.stringify(argument)); req.end(); req.on('error', function(error) { + if (error.code === 'ECONNRESET' || error.code === 'ETIMEDOUT') { + finishCall(false); + return; + } self.emit('error', new Error('Client error: ' + error.message)); self.running = false; }); diff --git a/src/node/performance/benchmark_server_express.js b/src/node/performance/benchmark_server_express.js index 065bcf660b6..4b695eb467d 100644 --- a/src/node/performance/benchmark_server_express.js +++ b/src/node/performance/benchmark_server_express.js @@ -46,7 +46,7 @@ var EventEmitter = require('events'); var util = require('util'); var express = require('express'); -var bodyParser = require('body-parser') +var bodyParser = require('body-parser'); function unaryCall(req, res) { var reqObj = req.body; @@ -56,7 +56,7 @@ function unaryCall(req, res) { function BenchmarkServer(host, port, tls, generic, response_size) { var app = express(); - app.use(bodyParser.json()) + app.use(bodyParser.json()); app.put('/serviceProto.BenchmarkService.service/unaryCall', unaryCall); this.input_host = host; this.input_port = port; From 9cb19b8e2429389dc68045aa7f61384f4b03660f Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 7 Apr 2017 14:17:41 -0700 Subject: [PATCH 04/21] support C++ error_details --- include/grpc++/impl/codegen/call.h | 55 +++++++++++++++------- include/grpc++/impl/codegen/status.h | 22 ++++++--- src/proto/grpc/testing/echo_messages.proto | 9 ++++ test/cpp/end2end/end2end_test.cc | 33 +++++++++++++ test/cpp/end2end/test_service_impl.cc | 5 ++ 5 files changed, 100 insertions(+), 24 deletions(-) diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h index be6857c4829..dd63c21ff17 100644 --- a/include/grpc++/impl/codegen/call.h +++ b/include/grpc++/impl/codegen/call.h @@ -63,21 +63,31 @@ class CallHook; class CompletionQueue; extern CoreCodegenInterface* g_core_codegen_interface; +const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin"; + // TODO(yangg) if the map is changed before we send, the pointers will be a // mess. Make sure it does not happen. inline grpc_metadata* FillMetadataArray( - const std::multimap& metadata) { - if (metadata.empty()) { + const std::multimap& metadata, + size_t* metadata_count, const grpc::string& optional_error_details) { + *metadata_count = metadata.size() + (optional_error_details.empty() ? 0 : 1); + if (*metadata_count == 0) { return nullptr; } grpc_metadata* metadata_array = (grpc_metadata*)(g_core_codegen_interface->gpr_malloc( - metadata.size() * sizeof(grpc_metadata))); + (*metadata_count) * sizeof(grpc_metadata))); size_t i = 0; for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) { metadata_array[i].key = SliceReferencingString(iter->first); metadata_array[i].value = SliceReferencingString(iter->second); } + if (!optional_error_details.empty()) { + metadata_array[i].key = + g_core_codegen_interface->grpc_slice_from_static_buffer( + kBinaryErrorDetailsKey, sizeof(kBinaryErrorDetailsKey) - 1); + metadata_array[i].value = SliceReferencingString(optional_error_details); + } return metadata_array; } @@ -216,8 +226,8 @@ class CallOpSendInitialMetadata { maybe_compression_level_.is_set = false; send_ = true; flags_ = flags; - initial_metadata_count_ = metadata.size(); - initial_metadata_ = FillMetadataArray(metadata); + initial_metadata_ = + FillMetadataArray(metadata, &initial_metadata_count_, ""); } void set_compression_level(grpc_compression_level level) { @@ -454,11 +464,12 @@ class CallOpServerSendStatus { void ServerSendStatus( const std::multimap& trailing_metadata, const Status& status) { - trailing_metadata_count_ = trailing_metadata.size(); - trailing_metadata_ = FillMetadataArray(trailing_metadata); + send_error_details_ = status.error_details(); + trailing_metadata_ = FillMetadataArray( + trailing_metadata, &trailing_metadata_count_, send_error_details_); send_status_available_ = true; send_status_code_ = static_cast(GetCanonicalCode(status)); - send_status_details_ = status.error_message(); + send_error_message_ = status.error_message(); } protected: @@ -470,9 +481,9 @@ class CallOpServerSendStatus { trailing_metadata_count_; op->data.send_status_from_server.trailing_metadata = trailing_metadata_; op->data.send_status_from_server.status = send_status_code_; - status_details_slice_ = SliceReferencingString(send_status_details_); + error_message_slice_ = SliceReferencingString(send_error_message_); op->data.send_status_from_server.status_details = - send_status_details_.empty() ? nullptr : &status_details_slice_; + send_error_message_.empty() ? nullptr : &error_message_slice_; op->flags = 0; op->reserved = NULL; } @@ -486,10 +497,11 @@ class CallOpServerSendStatus { private: bool send_status_available_; grpc_status_code send_status_code_; - grpc::string send_status_details_; + grpc::string send_error_details_; + grpc::string send_error_message_; size_t trailing_metadata_count_; grpc_metadata* trailing_metadata_; - grpc_slice status_details_slice_; + grpc_slice error_message_slice_; }; class CallOpRecvInitialMetadata { @@ -528,7 +540,7 @@ class CallOpClientRecvStatus { void ClientRecvStatus(ClientContext* context, Status* status) { metadata_map_ = &context->trailing_metadata_; recv_status_ = status; - status_details_ = g_core_codegen_interface->grpc_empty_slice(); + error_message_ = g_core_codegen_interface->grpc_empty_slice(); } protected: @@ -538,7 +550,7 @@ class CallOpClientRecvStatus { op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->data.recv_status_on_client.trailing_metadata = metadata_map_->arr(); op->data.recv_status_on_client.status = &status_code_; - op->data.recv_status_on_client.status_details = &status_details_; + op->data.recv_status_on_client.status_details = &error_message_; op->flags = 0; op->reserved = NULL; } @@ -546,10 +558,17 @@ class CallOpClientRecvStatus { void FinishOp(bool* status) { if (recv_status_ == nullptr) return; metadata_map_->FillMap(); + grpc::string binary_error_details; + auto iter = metadata_map_->map()->find(kBinaryErrorDetailsKey); + if (iter != metadata_map_->map()->end()) { + binary_error_details = + grpc::string(iter->second.begin(), iter->second.length()); + } *recv_status_ = Status(static_cast(status_code_), - grpc::string(GRPC_SLICE_START_PTR(status_details_), - GRPC_SLICE_END_PTR(status_details_))); - g_core_codegen_interface->grpc_slice_unref(status_details_); + grpc::string(GRPC_SLICE_START_PTR(error_message_), + GRPC_SLICE_END_PTR(error_message_)), + binary_error_details); + g_core_codegen_interface->grpc_slice_unref(error_message_); recv_status_ = nullptr; } @@ -557,7 +576,7 @@ class CallOpClientRecvStatus { MetadataMap* metadata_map_; Status* recv_status_; grpc_status_code status_code_; - grpc_slice status_details_; + grpc_slice error_message_; }; /// An abstract collection of CallOpSet's, to be used whenever diff --git a/include/grpc++/impl/codegen/status.h b/include/grpc++/impl/codegen/status.h index a509d311d42..5cce3c1672e 100644 --- a/include/grpc++/impl/codegen/status.h +++ b/include/grpc++/impl/codegen/status.h @@ -47,10 +47,16 @@ class Status { /// Construct an OK instance. Status() : code_(StatusCode::OK) {} - /// Construct an instance with associated \a code and \a details (also - // referred to as "error_message"). - Status(StatusCode code, const grpc::string& details) - : code_(code), details_(details) {} + /// Construct an instance with associated \a code and \a error_message + Status(StatusCode code, const grpc::string& error_message) + : code_(code), error_message_(error_message) {} + + /// Construct an instance with \a code, \a error_message and \a error_details + Status(StatusCode code, const grpc::string& error_message, + const grpc::string error_details) + : code_(code), + error_message_(error_message), + binary_error_details_(error_details) {} // Pre-defined special status objects. /// An OK pre-defined instance. @@ -61,14 +67,18 @@ class Status { /// Return the instance's error code. StatusCode error_code() const { return code_; } /// Return the instance's error message. - grpc::string error_message() const { return details_; } + grpc::string error_message() const { return error_message_; } + /// Return the (binary) error details. + // Usually it contains a serialized google.rpc.Status proto. + grpc::string error_details() const { return binary_error_details_; } /// Is the status OK? bool ok() const { return code_ == StatusCode::OK; } private: StatusCode code_; - grpc::string details_; + grpc::string error_message_; + grpc::string binary_error_details_; }; } // namespace grpc diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto index efb6f4d4935..b82e80d8e34 100644 --- a/src/proto/grpc/testing/echo_messages.proto +++ b/src/proto/grpc/testing/echo_messages.proto @@ -38,6 +38,13 @@ message DebugInfo { string detail = 2; } +// Error status client expects to see. +message ErrorStatus { + int32 code = 1; + string error_message = 2; + string binary_error_details = 3; +} + message RequestParams { bool echo_deadline = 1; int32 client_cancel_after_us = 2; @@ -51,6 +58,8 @@ message RequestParams { string expected_transport_security_type = 10; DebugInfo debug_info = 11; bool server_die = 12; // Server should not see a request with this set. + string binary_error_details = 13; + ErrorStatus expected_error = 14; } message EchoRequest { diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index d3a83b188f9..df71777e4bd 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1130,6 +1130,39 @@ TEST_P(End2endTest, BinaryTrailerTest) { EXPECT_TRUE(returned_info.ParseFromString(ToString(iter->second))); } +TEST_P(End2endTest, ExpectErrorTest) { + ResetStub(); + + std::vector expected_status; + expected_status.emplace_back(); + expected_status.back().set_code(13); // INTERNAL + expected_status.back().set_error_message("text error message"); + expected_status.back().set_binary_error_details("text error details"); + expected_status.emplace_back(); + expected_status.back().set_code(13); // INTERNAL + expected_status.back().set_error_message("text error message"); + expected_status.back().set_binary_error_details( + "\x0\x1\x2\x3\x4\x5\x6\x8\x9\xA\xB"); + + for (auto iter = expected_status.begin(); iter != expected_status.end(); + ++iter) { + EchoRequest request; + EchoResponse response; + ClientContext context; + request.set_message("Hello"); + auto* error = request.mutable_param()->mutable_expected_error(); + error->set_code(iter->code()); + error->set_error_message(iter->error_message()); + error->set_binary_error_details(iter->binary_error_details()); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_FALSE(s.ok()); + EXPECT_EQ(iter->code(), s.error_code()); + EXPECT_EQ(iter->error_message(), s.error_message()); + EXPECT_EQ(iter->binary_error_details(), s.error_details()); + } +} + ////////////////////////////////////////////////////////////////////////// // Test with and without a proxy. class ProxyEnd2endTest : public End2endTest { diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 11729c425cd..b473dd1f52e 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -92,6 +92,11 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, gpr_log(GPR_ERROR, "The request should not reach application handler."); GPR_ASSERT(0); } + if (request->has_param() && request->param().has_expected_error()) { + const auto& error = request->param().expected_error(); + return Status(static_cast(error.code()), error.error_message(), + error.binary_error_details()); + } int server_try_cancel = GetIntValueFromMetadata( kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); if (server_try_cancel > DO_NOT_CANCEL) { From e69881de7fd5a2f09ad92986c48e5fa2a013bb34 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Mon, 10 Apr 2017 14:29:43 -0700 Subject: [PATCH 05/21] Revise based on Mark's comments. --- BUILD | 2 + CMakeLists.txt | 2 + binding.gyp | 1 + build.yaml | 2 + config.m4 | 1 + gRPC-Core.podspec | 3 ++ grpc.gemspec | 2 + package.xml | 2 + src/core/tsi/transport_security.c | 9 ++-- src/core/tsi/transport_security.h | 12 +++-- src/core/tsi/transport_security_adapter. | 0 src/core/tsi/transport_security_adapter.c | 49 ++++++++++--------- src/core/tsi/transport_security_interface.h | 44 +++++++---------- src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 3 ++ vsprojects/vcxproj/grpc/grpc.vcxproj | 3 ++ vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 +++ 18 files changed, 86 insertions(+), 58 deletions(-) create mode 100644 src/core/tsi/transport_security_adapter. diff --git a/BUILD b/BUILD index 1991c867432..70ce0ecb6bd 100644 --- a/BUILD +++ b/BUILD @@ -1149,12 +1149,14 @@ grpc_cc_library( "src/core/tsi/fake_transport_security.c", "src/core/tsi/ssl_transport_security.c", "src/core/tsi/transport_security.c", + "src/core/tsi/transport_security_adapter.c", ], hdrs = [ "src/core/tsi/fake_transport_security.h", "src/core/tsi/ssl_transport_security.h", "src/core/tsi/ssl_types.h", "src/core/tsi/transport_security.h", + "src/core/tsi/transport_security_adapter.h", "src/core/tsi/transport_security_interface.h", ], external_deps = [ diff --git a/CMakeLists.txt b/CMakeLists.txt index f8b88645cb1..3b11066625c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1080,6 +1080,7 @@ add_library(grpc src/core/tsi/fake_transport_security.c src/core/tsi/ssl_transport_security.c src/core/tsi/transport_security.c + src/core/tsi/transport_security_adapter.c src/core/ext/transport/chttp2/server/chttp2_server.c src/core/ext/transport/chttp2/client/secure/secure_channel_create.c src/core/ext/filters/client_channel/channel_connectivity.c @@ -1425,6 +1426,7 @@ add_library(grpc_cronet src/core/tsi/fake_transport_security.c src/core/tsi/ssl_transport_security.c src/core/tsi/transport_security.c + src/core/tsi/transport_security_adapter.c src/core/ext/transport/chttp2/client/chttp2_connector.c src/core/ext/filters/load_reporting/load_reporting.c src/core/ext/filters/load_reporting/load_reporting_filter.c diff --git a/binding.gyp b/binding.gyp index 3444fa53dba..b64ff58f5c5 100644 --- a/binding.gyp +++ b/binding.gyp @@ -822,6 +822,7 @@ 'src/core/tsi/fake_transport_security.c', 'src/core/tsi/ssl_transport_security.c', 'src/core/tsi/transport_security.c', + 'src/core/tsi/transport_security_adapter.c', 'src/core/ext/transport/chttp2/server/chttp2_server.c', 'src/core/ext/transport/chttp2/client/secure/secure_channel_create.c', 'src/core/ext/filters/client_channel/channel_connectivity.c', diff --git a/build.yaml b/build.yaml index 6fbc8d91666..e5bec63ed0a 100644 --- a/build.yaml +++ b/build.yaml @@ -783,11 +783,13 @@ filegroups: - src/core/tsi/ssl_transport_security.h - src/core/tsi/ssl_types.h - src/core/tsi/transport_security.h + - src/core/tsi/transport_security_adapter.h - src/core/tsi/transport_security_interface.h src: - src/core/tsi/fake_transport_security.c - src/core/tsi/ssl_transport_security.c - src/core/tsi/transport_security.c + - src/core/tsi/transport_security_adapter.c deps: - gpr secure: true diff --git a/config.m4 b/config.m4 index 28467810313..1be815e3f34 100644 --- a/config.m4 +++ b/config.m4 @@ -256,6 +256,7 @@ if test "$PHP_GRPC" != "no"; then src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ + src/core/tsi/transport_security_adapter.c \ src/core/ext/transport/chttp2/server/chttp2_server.c \ src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \ src/core/ext/filters/client_channel/channel_connectivity.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 83c19afc243..78d2f157789 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -407,6 +407,7 @@ Pod::Spec.new do |s| 'src/core/tsi/ssl_transport_security.h', 'src/core/tsi/ssl_types.h', 'src/core/tsi/transport_security.h', + 'src/core/tsi/transport_security_adapter.h', 'src/core/tsi/transport_security_interface.h', 'src/core/ext/transport/chttp2/server/chttp2_server.h', 'src/core/ext/filters/client_channel/client_channel.h', @@ -631,6 +632,7 @@ Pod::Spec.new do |s| 'src/core/tsi/fake_transport_security.c', 'src/core/tsi/ssl_transport_security.c', 'src/core/tsi/transport_security.c', + 'src/core/tsi/transport_security_adapter.c', 'src/core/ext/transport/chttp2/server/chttp2_server.c', 'src/core/ext/transport/chttp2/client/secure/secure_channel_create.c', 'src/core/ext/filters/client_channel/channel_connectivity.c', @@ -857,6 +859,7 @@ Pod::Spec.new do |s| 'src/core/tsi/ssl_transport_security.h', 'src/core/tsi/ssl_types.h', 'src/core/tsi/transport_security.h', + 'src/core/tsi/transport_security_adapter.h', 'src/core/tsi/transport_security_interface.h', 'src/core/ext/transport/chttp2/server/chttp2_server.h', 'src/core/ext/filters/client_channel/client_channel.h', diff --git a/grpc.gemspec b/grpc.gemspec index 6a204685a03..abbd6f42518 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -323,6 +323,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/tsi/ssl_transport_security.h ) s.files += %w( src/core/tsi/ssl_types.h ) s.files += %w( src/core/tsi/transport_security.h ) + s.files += %w( src/core/tsi/transport_security_adapter.h ) s.files += %w( src/core/tsi/transport_security_interface.h ) s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.h ) s.files += %w( src/core/ext/filters/client_channel/client_channel.h ) @@ -547,6 +548,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/tsi/fake_transport_security.c ) s.files += %w( src/core/tsi/ssl_transport_security.c ) s.files += %w( src/core/tsi/transport_security.c ) + s.files += %w( src/core/tsi/transport_security_adapter.c ) s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.c ) s.files += %w( src/core/ext/transport/chttp2/client/secure/secure_channel_create.c ) s.files += %w( src/core/ext/filters/client_channel/channel_connectivity.c ) diff --git a/package.xml b/package.xml index 6957ecca731..7a301aa8300 100644 --- a/package.xml +++ b/package.xml @@ -332,6 +332,7 @@ + @@ -556,6 +557,7 @@ + diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c index a9cb6a107ca..aa8808ab74c 100644 --- a/src/core/tsi/transport_security.c +++ b/src/core/tsi/transport_security.c @@ -182,7 +182,7 @@ tsi_result tsi_handshaker_create_frame_protector( result = self->vtable->create_frame_protector(self, max_protected_frame_size, protector); if (result == TSI_OK) { - self->frame_protector_created = 1; + self->frame_protector_created = true; } return result; } @@ -206,7 +206,7 @@ void tsi_handshaker_destroy(tsi_handshaker *self) { /* --- tsi_handshaker_result implementation. --- */ -tsi_result tsi_handshaker_result_extract_peer(tsi_handshaker_result *self, +tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result *self, tsi_peer *peer) { if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT; memset(peer, 0, sizeof(tsi_peer)); @@ -214,7 +214,7 @@ tsi_result tsi_handshaker_result_extract_peer(tsi_handshaker_result *self, } tsi_result tsi_handshaker_result_create_frame_protector( - tsi_handshaker_result *self, size_t *max_protected_frame_size, + const tsi_handshaker_result *self, size_t *max_protected_frame_size, tsi_frame_protector **protector) { if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT; return self->vtable->create_frame_protector(self, max_protected_frame_size, @@ -222,7 +222,8 @@ tsi_result tsi_handshaker_result_create_frame_protector( } tsi_result tsi_handshaker_result_get_unused_bytes( - tsi_handshaker_result *self, unsigned char **bytes, size_t *bytes_size) { + const tsi_handshaker_result *self, unsigned char **bytes, + size_t *bytes_size) { if (self == NULL || bytes == NULL || bytes_size == NULL) { return TSI_INVALID_ARGUMENT; } diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h index 2e821108279..a4c9cbc0011 100644 --- a/src/core/tsi/transport_security.h +++ b/src/core/tsi/transport_security.h @@ -34,6 +34,8 @@ #ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_H #define GRPC_CORE_TSI_TRANSPORT_SECURITY_H +#include + #include "src/core/tsi/transport_security_interface.h" #ifdef __cplusplus @@ -90,18 +92,18 @@ typedef struct { struct tsi_handshaker { const tsi_handshaker_vtable *vtable; - int frame_protector_created; - int handshaker_result_created; + bool frame_protector_created; + bool handshaker_result_created; }; /* Base for tsi_handshaker_result implementations. See transport_security_interface.h for documentation. */ typedef struct { - tsi_result (*extract_peer)(tsi_handshaker_result *self, tsi_peer *peer); - tsi_result (*create_frame_protector)(tsi_handshaker_result *self, + tsi_result (*extract_peer)(const tsi_handshaker_result *self, tsi_peer *peer); + tsi_result (*create_frame_protector)(const tsi_handshaker_result *self, size_t *max_output_protected_frame_size, tsi_frame_protector **protector); - tsi_result (*get_unused_bytes)(tsi_handshaker_result *self, + tsi_result (*get_unused_bytes)(const tsi_handshaker_result *self, unsigned char **bytes, size_t *bytes_size); void (*destroy)(tsi_handshaker_result *self); } tsi_handshaker_result_vtable; diff --git a/src/core/tsi/transport_security_adapter. b/src/core/tsi/transport_security_adapter. new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c index 7e0b8f574a0..60cebdd6f25 100644 --- a/src/core/tsi/transport_security_adapter.c +++ b/src/core/tsi/transport_security_adapter.c @@ -50,14 +50,14 @@ typedef struct { size_t unused_bytes_size; } tsi_adapter_handshaker_result; -static tsi_result tsi_adapter_result_extract_peer(tsi_handshaker_result *self, - tsi_peer *peer) { +static tsi_result tsi_adapter_result_extract_peer( + const tsi_handshaker_result *self, tsi_peer *peer) { tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; return tsi_handshaker_extract_peer(impl->handshaker, peer); } static tsi_result tsi_adapter_result_create_frame_protector( - tsi_handshaker_result *self, size_t *max_output_protected_frame_size, + const tsi_handshaker_result *self, size_t *max_output_protected_frame_size, tsi_frame_protector **protector) { tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; return tsi_handshaker_create_frame_protector( @@ -65,7 +65,8 @@ static tsi_result tsi_adapter_result_create_frame_protector( } static tsi_result tsi_adapter_result_get_unused_bytes( - tsi_handshaker_result *self, unsigned char **bytes, size_t *byte_size) { + const tsi_handshaker_result *self, unsigned char **bytes, + size_t *byte_size) { tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; *bytes = impl->unused_bytes; *byte_size = impl->unused_bytes_size; @@ -74,9 +75,7 @@ static tsi_result tsi_adapter_result_get_unused_bytes( static void tsi_adapter_result_destroy(tsi_handshaker_result *self) { tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; - if (impl->unused_bytes != NULL) { - gpr_free(impl->unused_bytes); - } + gpr_free(impl->unused_bytes); gpr_free(self); } @@ -114,45 +113,45 @@ typedef struct { size_t adapter_buffer_size; } tsi_adapter_handshaker; -tsi_result tsi_adapter_get_bytes_to_send_to_peer(tsi_handshaker *self, - unsigned char *bytes, - size_t *bytes_size) { +static tsi_result tsi_adapter_get_bytes_to_send_to_peer(tsi_handshaker *self, + unsigned char *bytes, + size_t *bytes_size) { return tsi_handshaker_get_bytes_to_send_to_peer( tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size); } -tsi_result tsi_adapter_process_bytes_from_peer(tsi_handshaker *self, - const unsigned char *bytes, - size_t *bytes_size) { +static tsi_result tsi_adapter_process_bytes_from_peer( + tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) { return tsi_handshaker_process_bytes_from_peer( tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size); } -tsi_result tsi_adapter_get_result(tsi_handshaker *self) { +static tsi_result tsi_adapter_get_result(tsi_handshaker *self) { return tsi_handshaker_get_result(tsi_adapter_handshaker_get_wrapped(self)); } -tsi_result tsi_adapter_extract_peer(tsi_handshaker *self, tsi_peer *peer) { +static tsi_result tsi_adapter_extract_peer(tsi_handshaker *self, + tsi_peer *peer) { return tsi_handshaker_extract_peer(tsi_adapter_handshaker_get_wrapped(self), peer); } -tsi_result tsi_adapter_create_frame_protector(tsi_handshaker *self, - size_t *max_protected_frame_size, - tsi_frame_protector **protector) { +static tsi_result tsi_adapter_create_frame_protector( + tsi_handshaker *self, size_t *max_protected_frame_size, + tsi_frame_protector **protector) { return tsi_handshaker_create_frame_protector( tsi_adapter_handshaker_get_wrapped(self), max_protected_frame_size, protector); } -void tsi_adapter_destroy(tsi_handshaker *self) { +static void tsi_adapter_destroy(tsi_handshaker *self) { tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)self; tsi_handshaker_destroy(impl->wrapped); gpr_free(impl->adapter_buffer); gpr_free(self); } -tsi_result tsi_adapter_next( +static tsi_result tsi_adapter_next( tsi_handshaker *self, const unsigned char *received_bytes, size_t received_bytes_size, unsigned char **bytes_to_send, size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result, @@ -196,11 +195,15 @@ tsi_result tsi_adapter_next( size_t unused_bytes_size = received_bytes_size - bytes_consumed; const unsigned char *unused_bytes = unused_bytes_size == 0 ? NULL : received_bytes + bytes_consumed; - return tsi_adapter_create_handshaker_result( + status = tsi_adapter_create_handshaker_result( impl->wrapped, unused_bytes, unused_bytes_size, handshaker_result); + if (status == TSI_OK) { + impl->base.handshaker_result_created = true; + } + } else { + *handshaker_result = NULL; } - *handshaker_result = NULL; - return TSI_OK; + return status; } static const tsi_handshaker_vtable handshaker_vtable = { diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index be04810e24f..c9495f80b6d 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -220,22 +220,22 @@ typedef struct tsi_handshaker_result tsi_handshaker_result; /* This method extracts tsi peer. It returns TSI_OK assuming there is no fatal error. The caller is responsible for destructing the peer. */ -tsi_result tsi_handshaker_result_extract_peer(tsi_handshaker_result *self, +tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result *self, tsi_peer *peer); /* This method creates a tsi_frame_protector object. It returns TSI_OK assuming there is no fatal error. The caller is responsible for destroying the protector. */ tsi_result tsi_handshaker_result_create_frame_protector( - tsi_handshaker_result *self, size_t *max_output_protected_frame_size, + const tsi_handshaker_result *self, size_t *max_output_protected_frame_size, tsi_frame_protector **protector); /* This method returns the unused bytes from the handshake. It returns TSI_OK assuming there is no fatal error. The caller should not free the bytes. */ -tsi_result tsi_handshaker_result_get_unused_bytes(tsi_handshaker_result *self, - unsigned char **bytes, - size_t *byte_size); +tsi_result tsi_handshaker_result_get_unused_bytes( + const tsi_handshaker_result *self, unsigned char **bytes, + size_t *byte_size); /* This method releases the tsi_handshaker_handshaker object. After this method is called, no other method can be called on the object. */ @@ -305,8 +305,8 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self); ... ------------------------------------------------------------------------ - A typical usage of the new TSI would be as follows, supporting both - synchronous and asynchrnous TSI handshaker implementations: + A typical usage supporting both synchronous and asynchronous TSI handshaker + implementations would be: ------------------------------------------------------------------------ @@ -324,17 +324,6 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self); ... } - // This method is a wrapper of the callback function to execute when - // tsi_handshaker_next finishes. It is passed to tsi_handshaker_next as - // the callback function. - void on_handshake_next_done_wrapper( - tsi_result status, void *user_data, const unsigned char *bytes_to_send, - size_t bytes_to_send_size, tsi_handshaker_result *result) { - security_handshaker *h = (security_handshaker *)user_data; - on_handshake_next_done(h, status, bytes_to_send, - bytes_to_send_size, result); - } - // This method is the callback function when there are data received from // the peer. This method will read bytes into the handshake buffer and call // do_handshake_next. @@ -355,19 +344,22 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self); tsi_handshaker_result *result = NULL; status = tsi_handshaker_next( handshaker, bytes_received, bytes_received_size, &bytes_to_send, - &bytes_to_send_size, &result, on_handshake_next_done_wrapper, h); + &bytes_to_send_size, &result, on_handshake_next_done, h); // If TSI handshaker is asynchronous, on_handshake_next_done will be - // called during the execution of the callback function. + // executed inside tsi_handshaker_next. if (status == TSI_ASYNC) return; - on_handshake_next_done(h, status, bytes_to_send, + // If TSI handshaker is synchronous, invoke callback directly in this + // thread. + on_handshake_next_done(status, (void *)h, bytes_to_send, bytes_to_send_size, result); } - // This is the real function to execute after tsi_handshaker_next. + // This is the callback function to execute after tsi_handshaker_next. + // It is passed to tsi_handshaker_next as a function parameter. void on_handshake_next_done( - security_handshaker *h, tsi_result status, - const unsigned char *bytes_to_send, size_t bytes_to_send_size, - tsi_handshaker_result *result) { + tsi_result status, void *user_data, const unsigned char *bytes_to_send, + size_t bytes_to_send_size, tsi_handshaker_result *result) { + security_handshaker *h = (security_handshaker *)user_data; if (status == TSI_INCOMPLETE_DATA) { // Schedule an asynchronous read from the peer. If handshake data are // received, on_handshake_data_received_from_peer will be called. @@ -386,7 +378,7 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self); // Check the Peer. tsi_peer peer; status = tsi_handshaker_result_extract_peer(result, &peer); - if (status != TSI_OK) return status; + if (status != TSI_OK) return; status = check_peer(&peer); tsi_peer_destruct(&peer); if (status != TSI_OK) return; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 3bcbe667e2c..88e783815c7 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -250,6 +250,7 @@ CORE_SOURCE_FILES = [ 'src/core/tsi/fake_transport_security.c', 'src/core/tsi/ssl_transport_security.c', 'src/core/tsi/transport_security.c', + 'src/core/tsi/transport_security_adapter.c', 'src/core/ext/transport/chttp2/server/chttp2_server.c', 'src/core/ext/transport/chttp2/client/secure/secure_channel_create.c', 'src/core/ext/filters/client_channel/channel_connectivity.c', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 6903a0e5d5a..55a707d9197 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1369,6 +1369,8 @@ src/core/tsi/ssl_transport_security.h \ src/core/tsi/ssl_types.h \ src/core/tsi/transport_security.c \ src/core/tsi/transport_security.h \ +src/core/tsi/transport_security_adapter.c \ +src/core/tsi/transport_security_adapter.h \ src/core/tsi/transport_security_interface.h \ third_party/nanopb/pb.h \ third_party/nanopb/pb_common.c \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 11176d97567..c871256d6ed 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8578,6 +8578,7 @@ "src/core/tsi/ssl_transport_security.h", "src/core/tsi/ssl_types.h", "src/core/tsi/transport_security.h", + "src/core/tsi/transport_security_adapter.h", "src/core/tsi/transport_security_interface.h" ], "is_filegroup": true, @@ -8591,6 +8592,8 @@ "src/core/tsi/ssl_types.h", "src/core/tsi/transport_security.c", "src/core/tsi/transport_security.h", + "src/core/tsi/transport_security_adapter.c", + "src/core/tsi/transport_security_adapter.h", "src/core/tsi/transport_security_interface.h" ], "third_party": false, diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 948af2f29ee..1fec7fb353d 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -452,6 +452,7 @@ + @@ -852,6 +853,8 @@ + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index d43b0e3f83e..28776121ecd 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -523,6 +523,9 @@ src\core\tsi + + src\core\tsi + src\core\ext\transport\chttp2\server @@ -1253,6 +1256,9 @@ src\core\tsi + + src\core\tsi + src\core\tsi From a2a2024944a92ec1dbf0ec827659ee408cb4c1e3 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Mon, 10 Apr 2017 15:03:21 -0700 Subject: [PATCH 06/21] Use handshaker_result_created in tsi_adapter_handshaker --- src/core/tsi/transport_security_adapter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c index 60cebdd6f25..ebf02791396 100644 --- a/src/core/tsi/transport_security_adapter.c +++ b/src/core/tsi/transport_security_adapter.c @@ -191,7 +191,9 @@ static tsi_result tsi_adapter_next( *bytes_to_send_size = offset; /* If handshake completes, create tsi_handshaker_result. */ - if (!tsi_handshaker_is_in_progress(impl->wrapped)) { + if (tsi_handshaker_is_in_progress(impl->wrapped)) { + *handshaker_result = NULL; + } else { size_t unused_bytes_size = received_bytes_size - bytes_consumed; const unsigned char *unused_bytes = unused_bytes_size == 0 ? NULL : received_bytes + bytes_consumed; @@ -200,8 +202,6 @@ static tsi_result tsi_adapter_next( if (status == TSI_OK) { impl->base.handshaker_result_created = true; } - } else { - *handshaker_result = NULL; } return status; } From c19550272e4883c30ab50e301617b3e04e8db39a Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Tue, 11 Apr 2017 09:36:19 -0700 Subject: [PATCH 07/21] Revise based on Julien's comments. --- src/core/tsi/transport_security.c | 36 +++++++++ src/core/tsi/transport_security_adapter.c | 62 +++++++------- src/core/tsi/transport_security_adapter.h | 11 ++- src/core/tsi/transport_security_interface.h | 89 ++++----------------- 4 files changed, 93 insertions(+), 105 deletions(-) diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c index aa8808ab74c..b11c00c43c4 100644 --- a/src/core/tsi/transport_security.c +++ b/src/core/tsi/transport_security.c @@ -94,6 +94,9 @@ tsi_result tsi_frame_protector_protect(tsi_frame_protector *self, protected_output_frames_size == NULL) { return TSI_INVALID_ARGUMENT; } + if (self->vtable == NULL || self->vtable->protect == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->protect(self, unprotected_bytes, unprotected_bytes_size, protected_output_frames, protected_output_frames_size); @@ -106,6 +109,9 @@ tsi_result tsi_frame_protector_protect_flush( protected_output_frames_size == NULL || still_pending_size == NULL) { return TSI_INVALID_ARGUMENT; } + if (self->vtable == NULL || self->vtable->protect_flush == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->protect_flush(self, protected_output_frames, protected_output_frames_size, still_pending_size); @@ -120,6 +126,9 @@ tsi_result tsi_frame_protector_unprotect( unprotected_bytes_size == NULL) { return TSI_INVALID_ARGUMENT; } + if (self->vtable == NULL || self->vtable->unprotect == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->unprotect(self, protected_frames_bytes, protected_frames_bytes_size, unprotected_bytes, unprotected_bytes_size); @@ -141,6 +150,9 @@ tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, return TSI_INVALID_ARGUMENT; } if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; + if (self->vtable == NULL || self->vtable->get_bytes_to_send_to_peer == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size); } @@ -151,12 +163,18 @@ tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, return TSI_INVALID_ARGUMENT; } if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; + if (self->vtable == NULL || self->vtable->process_bytes_from_peer == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->process_bytes_from_peer(self, bytes, bytes_size); } tsi_result tsi_handshaker_get_result(tsi_handshaker *self) { if (self == NULL) return TSI_INVALID_ARGUMENT; if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; + if (self->vtable == NULL || self->vtable->get_result == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->get_result(self); } @@ -167,6 +185,9 @@ tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer) { if (tsi_handshaker_get_result(self) != TSI_OK) { return TSI_FAILED_PRECONDITION; } + if (self->vtable == NULL || self->vtable->extract_peer == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->extract_peer(self, peer); } @@ -179,6 +200,9 @@ tsi_result tsi_handshaker_create_frame_protector( if (tsi_handshaker_get_result(self) != TSI_OK) { return TSI_FAILED_PRECONDITION; } + if (self->vtable == NULL || self->vtable->create_frame_protector == NULL) { + return TSI_UNIMPLEMENTED; + } result = self->vtable->create_frame_protector(self, max_protected_frame_size, protector); if (result == TSI_OK) { @@ -194,6 +218,9 @@ tsi_result tsi_handshaker_next( tsi_handshaker_on_next_done_cb cb, void *user_data) { if (self == NULL) return TSI_INVALID_ARGUMENT; if (self->handshaker_result_created) return TSI_FAILED_PRECONDITION; + if (self->vtable == NULL || self->vtable->next == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->next(self, received_bytes, received_bytes_size, bytes_to_send, bytes_to_send_size, handshaker_result, cb, user_data); @@ -210,6 +237,9 @@ tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result *self, tsi_peer *peer) { if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT; memset(peer, 0, sizeof(tsi_peer)); + if (self->vtable == NULL || self->vtable->extract_peer == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->extract_peer(self, peer); } @@ -217,6 +247,9 @@ tsi_result tsi_handshaker_result_create_frame_protector( const tsi_handshaker_result *self, size_t *max_protected_frame_size, tsi_frame_protector **protector) { if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT; + if (self->vtable == NULL || self->vtable->create_frame_protector == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->create_frame_protector(self, max_protected_frame_size, protector); } @@ -227,6 +260,9 @@ tsi_result tsi_handshaker_result_get_unused_bytes( if (self == NULL || bytes == NULL || bytes_size == NULL) { return TSI_INVALID_ARGUMENT; } + if (self->vtable == NULL || self->vtable->get_unused_bytes == NULL) { + return TSI_UNIMPLEMENTED; + } return self->vtable->get_unused_bytes(self, bytes, bytes_size); } diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c index ebf02791396..d83339b3eb5 100644 --- a/src/core/tsi/transport_security_adapter.c +++ b/src/core/tsi/transport_security_adapter.c @@ -45,26 +45,26 @@ typedef struct { tsi_handshaker_result base; - tsi_handshaker *handshaker; + tsi_handshaker *wrapped; unsigned char *unused_bytes; size_t unused_bytes_size; } tsi_adapter_handshaker_result; -static tsi_result tsi_adapter_result_extract_peer( - const tsi_handshaker_result *self, tsi_peer *peer) { +static tsi_result adapter_result_extract_peer(const tsi_handshaker_result *self, + tsi_peer *peer) { tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; - return tsi_handshaker_extract_peer(impl->handshaker, peer); + return tsi_handshaker_extract_peer(impl->wrapped, peer); } -static tsi_result tsi_adapter_result_create_frame_protector( +static tsi_result adapter_result_create_frame_protector( const tsi_handshaker_result *self, size_t *max_output_protected_frame_size, tsi_frame_protector **protector) { tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; return tsi_handshaker_create_frame_protector( - impl->handshaker, max_output_protected_frame_size, protector); + impl->wrapped, max_output_protected_frame_size, protector); } -static tsi_result tsi_adapter_result_get_unused_bytes( +static tsi_result adapter_result_get_unused_bytes( const tsi_handshaker_result *self, unsigned char **bytes, size_t *byte_size) { tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; @@ -73,26 +73,26 @@ static tsi_result tsi_adapter_result_get_unused_bytes( return TSI_OK; } -static void tsi_adapter_result_destroy(tsi_handshaker_result *self) { +static void adapter_result_destroy(tsi_handshaker_result *self) { tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; gpr_free(impl->unused_bytes); gpr_free(self); } static const tsi_handshaker_result_vtable result_vtable = { - tsi_adapter_result_extract_peer, tsi_adapter_result_create_frame_protector, - tsi_adapter_result_get_unused_bytes, tsi_adapter_result_destroy, + adapter_result_extract_peer, adapter_result_create_frame_protector, + adapter_result_get_unused_bytes, adapter_result_destroy, }; tsi_result tsi_adapter_create_handshaker_result( - tsi_handshaker *handshaker, const unsigned char *unused_bytes, + tsi_handshaker *wrapped, const unsigned char *unused_bytes, size_t unused_bytes_size, tsi_handshaker_result **handshaker_result) { - if (handshaker == NULL || (unused_bytes_size > 0 && unused_bytes == NULL)) { + if (wrapped == NULL || (unused_bytes_size > 0 && unused_bytes == NULL)) { return TSI_INVALID_ARGUMENT; } tsi_adapter_handshaker_result *impl = gpr_zalloc(sizeof(*impl)); impl->base.vtable = &result_vtable; - impl->handshaker = handshaker; + impl->wrapped = wrapped; impl->unused_bytes_size = unused_bytes_size; if (unused_bytes_size > 0) { impl->unused_bytes = gpr_malloc(unused_bytes_size); @@ -113,30 +113,30 @@ typedef struct { size_t adapter_buffer_size; } tsi_adapter_handshaker; -static tsi_result tsi_adapter_get_bytes_to_send_to_peer(tsi_handshaker *self, - unsigned char *bytes, - size_t *bytes_size) { +static tsi_result adapter_get_bytes_to_send_to_peer(tsi_handshaker *self, + unsigned char *bytes, + size_t *bytes_size) { return tsi_handshaker_get_bytes_to_send_to_peer( tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size); } -static tsi_result tsi_adapter_process_bytes_from_peer( - tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) { +static tsi_result adapter_process_bytes_from_peer(tsi_handshaker *self, + const unsigned char *bytes, + size_t *bytes_size) { return tsi_handshaker_process_bytes_from_peer( tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size); } -static tsi_result tsi_adapter_get_result(tsi_handshaker *self) { +static tsi_result adapter_get_result(tsi_handshaker *self) { return tsi_handshaker_get_result(tsi_adapter_handshaker_get_wrapped(self)); } -static tsi_result tsi_adapter_extract_peer(tsi_handshaker *self, - tsi_peer *peer) { +static tsi_result adapter_extract_peer(tsi_handshaker *self, tsi_peer *peer) { return tsi_handshaker_extract_peer(tsi_adapter_handshaker_get_wrapped(self), peer); } -static tsi_result tsi_adapter_create_frame_protector( +static tsi_result adapter_create_frame_protector( tsi_handshaker *self, size_t *max_protected_frame_size, tsi_frame_protector **protector) { return tsi_handshaker_create_frame_protector( @@ -144,14 +144,14 @@ static tsi_result tsi_adapter_create_frame_protector( protector); } -static void tsi_adapter_destroy(tsi_handshaker *self) { +static void adapter_destroy(tsi_handshaker *self) { tsi_adapter_handshaker *impl = (tsi_adapter_handshaker *)self; tsi_handshaker_destroy(impl->wrapped); gpr_free(impl->adapter_buffer); gpr_free(self); } -static tsi_result tsi_adapter_next( +static tsi_result adapter_next( tsi_handshaker *self, const unsigned char *received_bytes, size_t received_bytes_size, unsigned char **bytes_to_send, size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result, @@ -207,13 +207,13 @@ static tsi_result tsi_adapter_next( } static const tsi_handshaker_vtable handshaker_vtable = { - tsi_adapter_get_bytes_to_send_to_peer, - tsi_adapter_process_bytes_from_peer, - tsi_adapter_get_result, - tsi_adapter_extract_peer, - tsi_adapter_create_frame_protector, - tsi_adapter_destroy, - tsi_adapter_next, + adapter_get_bytes_to_send_to_peer, + adapter_process_bytes_from_peer, + adapter_get_result, + adapter_extract_peer, + adapter_create_frame_protector, + adapter_destroy, + adapter_next, }; tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped) { diff --git a/src/core/tsi/transport_security_adapter.h b/src/core/tsi/transport_security_adapter.h index de5aaefd5f1..686618b53b1 100644 --- a/src/core/tsi/transport_security_adapter.h +++ b/src/core/tsi/transport_security_adapter.h @@ -41,11 +41,18 @@ extern "C" { #endif /* Create a tsi handshaker that takes an implementation of old interface and - converts into an implementation of new interface. + converts into an implementation of new interface. In the old interface, + there are get_bytes_to_send_to_peer, process_bytes_from_peer, get_result, + extract_peer, and create_frame_protector. In the new interface, only next + method is needed. See transport_security_interface.h for details. Note that + this tsi adapter handshaker is temporary. It will be removed once TSI has + been fully migrated to the new interface. Ownership of input tsi_handshaker is transferred to this new adapter. */ tsi_handshaker *tsi_create_adapter_handshaker(tsi_handshaker *wrapped); -/* Given a tsi adapter handshaker, return the original wrapped handshaker. */ +/* Given a tsi adapter handshaker, return the original wrapped handshaker. The + adapter still owns the wrapped handshaker which should not be destroyed by + the caller. */ tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter); #ifdef __cplusplus diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index c9495f80b6d..f2112b62b67 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -232,7 +232,8 @@ tsi_result tsi_handshaker_result_create_frame_protector( /* This method returns the unused bytes from the handshake. It returns TSI_OK assuming there is no fatal error. - The caller should not free the bytes. */ + Ownership of the bytes is retained by the handshaker result. As a + consequence, the caller must not free the bytes. */ tsi_result tsi_handshaker_result_get_unused_bytes( const tsi_handshaker_result *self, unsigned char **bytes, size_t *byte_size); @@ -247,64 +248,6 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self); ------------------------------------------------------------------------ - A typical usage of the synchronous TSI handshaker would be: - - ------------------------------------------------------------------------ - tsi_result status = TSI_OK; - unsigned char buf[4096]; - const size_t buf_size = 4906; - size_t bytes_received_size = 0; - unsigned char *bytes_to_send = NULL; - size_t bytes_to_send_size = 0; - tsi_handshaker_result *result = NULL; - - while (1) { - status = tsi_handshaker_next( - handshaker, buf, bytes_received_size, - &bytes_to_send, &bytes_to_send_size, &result, NULL, NULL); - if (status == TSI_INCOMPLETE_DATA) { - // Need more data from the peer. - bytes_received_size = buf_size; - read_bytes_from_peer(buf, &bytes_received_size); - continue; - } - if (status != TSI_OK) return status; - if (bytes_to_send_size > 0) { - send_bytes_to_peer(bytes_to_send, bytes_to_send_size); - } - if (result != NULL) break; - bytes_received_size = buf_size; - read_bytes_from_peer(buf, &bytes_received_size); - } - - // Check the Peer. - tsi_peer peer; - status = tsi_handshaker_result_extract_peer(result, &peer); - if (status != TSI_OK) return status; - status = check_peer(&peer); - tsi_peer_destruct(&peer); - if (status != TSI_OK) return status; - - // Create the protector. - tsi_frame_protector* protector = NULL; - status = tsi_handshaker_result_create_frame_protector(result, NULL, - &protector); - if (status != TSI_OK) return status; - - // Do not forget to unprotect outstanding data if any. - unsigned char *unused_bytes = NULL; - size_t unused_bytes_size = 0; - status = tsi_handshaker_result_get_unused_bytes(result, &unused_bytes, - &unused_bytes_size); - if (status != TSI_OK) return status; - if (unused_bytes_size > 0) { - status = tsi_frame_protector_unprotect(protector, unused_bytes, - unused_bytes_size, ..., ...); - .... - } - ... - ------------------------------------------------------------------------ - A typical usage supporting both synchronous and asynchronous TSI handshaker implementations would be: @@ -324,8 +267,8 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self); ... } - // This method is the callback function when there are data received from - // the peer. This method will read bytes into the handshake buffer and call + // This method is the callback function when data is received from the + // peer. This method will read bytes into the handshake buffer and call // do_handshake_next. void on_handshake_data_received_from_peer(void *user_data) { security_handshaker *h = (security_handshaker *)user_data; @@ -396,7 +339,7 @@ void tsi_handshaker_result_destroy(tsi_handshaker_result *self); ------------------------------------------------------------------------ */ typedef struct tsi_handshaker tsi_handshaker; -/* TO BE DEPRECATED SOON. +/* TO BE DEPRECATED SOON. Use tsi_handshaker_next instead. Gets bytes that need to be sent to the peer. - bytes is the buffer that will be written with the data to be sent to the peer. @@ -412,7 +355,7 @@ tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size); -/* TO BE DEPRECATED SOON. +/* TO BE DEPRECATED SOON. Use tsi_handshaker_next instead. Processes bytes received from the peer. - bytes is the buffer containing the data. - bytes_size is an input/output parameter specifying the size of the data as @@ -439,14 +382,15 @@ tsi_result tsi_handshaker_get_result(tsi_handshaker *self); #define tsi_handshaker_is_in_progress(h) \ (tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS) -/* TO BE DEPRECATED SOON. +/* TO BE DEPRECATED SOON. Use tsi_handshaker_result_extract_peer instead. This method may return TSI_FAILED_PRECONDITION if tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise assuming the handshaker is not in a fatal error state. The caller is responsible for destructing the peer. */ tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer); -/* TO BE DEPRECATED SOON. +/* TO BE DEPRECATED SOON. Use tsi_handshaker_result_create_frame_protector + instead. This method creates a tsi_frame_protector object after the handshake phase is done. After this method has been called successfully, the only method that can be called on this object is Destroy. @@ -488,13 +432,14 @@ typedef void (*tsi_handshaker_on_next_done_cb)( TSI handshaker implementation. - user_data is the argument to callback function passed from the caller. This method returns TSI_ASYNC if the TSI handshaker implementation is - asynchronous. It returns TSI_OK if the handshake completes or if there are - data to send to the peer, otherwise returns TSI_INCOMPLETE_DATA which - indicates that this method needs to be called again with more data from the - peer. In case of a fatal error in the handshake, another specific error code - is returned. - The caller is responsible for destroying the handshaker_result. However, the - caller should not free bytes_to_send, as the buffer is owned by the + asynchronous, and in this case, the callback is guaranteed to run in another + thread owned by TSI. It returns TSI_OK if the handshake completes or if + there are data to send to the peer, otherwise returns TSI_INCOMPLETE_DATA + which indicates that this method needs to be called again with more data + from the peer. In case of a fatal error in the handshake, another specific + error code is returned. + The caller is responsible for destroying the handshaker_result. However, + the caller should not free bytes_to_send, as the buffer is owned by the tsi_handshaker object. */ tsi_result tsi_handshaker_next( tsi_handshaker *self, const unsigned char *received_bytes, From c953b62d396d6168507520d837550f6b12d7e729 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Tue, 11 Apr 2017 10:16:19 -0700 Subject: [PATCH 08/21] Transfer ownership of tsi_handshaker in adapter_create_result. --- src/core/tsi/transport_security_adapter. | 0 src/core/tsi/transport_security_adapter.c | 5 ++++- 2 files changed, 4 insertions(+), 1 deletion(-) delete mode 100644 src/core/tsi/transport_security_adapter. diff --git a/src/core/tsi/transport_security_adapter. b/src/core/tsi/transport_security_adapter. deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c index d83339b3eb5..9f2147b5301 100644 --- a/src/core/tsi/transport_security_adapter.c +++ b/src/core/tsi/transport_security_adapter.c @@ -75,6 +75,7 @@ static tsi_result adapter_result_get_unused_bytes( static void adapter_result_destroy(tsi_handshaker_result *self) { tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; + tsi_handshaker_destroy(impl->wrapped); gpr_free(impl->unused_bytes); gpr_free(self); } @@ -84,7 +85,8 @@ static const tsi_handshaker_result_vtable result_vtable = { adapter_result_get_unused_bytes, adapter_result_destroy, }; -tsi_result tsi_adapter_create_handshaker_result( +/* Ownership of wrapped tsi_handshaker is transferred to the result object. */ +static tsi_result tsi_adapter_create_handshaker_result( tsi_handshaker *wrapped, const unsigned char *unused_bytes, size_t unused_bytes_size, tsi_handshaker_result **handshaker_result) { if (wrapped == NULL || (unused_bytes_size > 0 && unused_bytes == NULL)) { @@ -201,6 +203,7 @@ static tsi_result adapter_next( impl->wrapped, unused_bytes, unused_bytes_size, handshaker_result); if (status == TSI_OK) { impl->base.handshaker_result_created = true; + impl->wrapped = NULL; } } return status; From 423d6fd7ed418aead7d494e8d3c31ecd6e2743f1 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 13:15:45 -0700 Subject: [PATCH 09/21] Optimize framing a little - rely on the fact that data-to-come holds a reference to data-being-written, so there's no need to add a ref for every frame written - provide an 'inlined' version of grpc_slice_malloc (via a #define) that gives the compiler more information about small allocations to enable better optimization --- include/grpc/slice.h | 10 ++ include/grpc/slice_buffer.h | 4 + .../lb_policy/grpclb/load_balancer_api.c | 2 +- .../transport/chttp2/transport/bin_decoder.c | 4 +- .../transport/chttp2/transport/bin_encoder.c | 6 +- .../chttp2/transport/chttp2_transport.c | 8 +- .../transport/chttp2/transport/frame_data.c | 4 +- .../transport/chttp2/transport/frame_goaway.c | 2 +- .../transport/chttp2/transport/frame_ping.c | 2 +- .../chttp2/transport/frame_rst_stream.c | 2 +- .../chttp2/transport/frame_settings.c | 4 +- .../chttp2/transport/frame_window_update.c | 2 +- .../chttp2/transport/hpack_encoder.c | 2 +- .../cronet/transport/cronet_transport.c | 2 +- src/core/lib/channel/http_client_filter.c | 2 +- src/core/lib/compression/message_compress.c | 4 +- src/core/lib/iomgr/tcp_windows.c | 2 +- .../lib/security/transport/secure_endpoint.c | 8 +- src/core/lib/slice/b64.c | 2 +- src/core/lib/slice/percent_encoding.c | 6 +- src/core/lib/slice/slice.c | 95 +++++++++++++------ src/core/lib/slice/slice_buffer.c | 36 ++++++- src/core/lib/surface/byte_buffer_reader.c | 2 +- 23 files changed, 150 insertions(+), 61 deletions(-) diff --git a/include/grpc/slice.h b/include/grpc/slice.h index ea66e094e98..4dce6da9155 100644 --- a/include/grpc/slice.h +++ b/include/grpc/slice.h @@ -75,6 +75,13 @@ GPRAPI grpc_slice grpc_slice_new_with_len(void *p, size_t len, call. Aborts if malloc() fails. */ GPRAPI grpc_slice grpc_slice_malloc(size_t length); +GPRAPI grpc_slice grpc_slice_malloc_large(size_t length); + +#define GRPC_SLICE_MALLOC(len) \ + ((len) <= GRPC_SLICE_INLINED_SIZE \ + ? (grpc_slice){.refcount = NULL, \ + .data.inlined = {.length = (uint8_t)(len)}} \ + : grpc_slice_malloc_large((len))) /* Intern a slice: @@ -117,6 +124,9 @@ GPRAPI grpc_slice grpc_slice_sub_no_ref(grpc_slice s, size_t begin, size_t end); Requires s intialized, split <= s.length */ GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice *s, size_t split); +/* The same as grpc_slice_split_tail, but without altering refcounts */ +GPRAPI grpc_slice grpc_slice_split_tail_no_ref(grpc_slice *s, size_t split); + /* Splits s into two: modifies s to be s[split:s.length], and returns a new slice, sharing a refcount with s, that contains s[0:split]. Requires s intialized, split <= s.length */ diff --git a/include/grpc/slice_buffer.h b/include/grpc/slice_buffer.h index 2ed896645b4..cdbd74776c6 100644 --- a/include/grpc/slice_buffer.h +++ b/include/grpc/slice_buffer.h @@ -77,6 +77,10 @@ GPRAPI void grpc_slice_buffer_trim_end(grpc_slice_buffer *src, size_t n, /* move the first n bytes of src into dst */ GPRAPI void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n, grpc_slice_buffer *dst); +/* move the first n bytes of src into dst without adding references */ +GPRAPI void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer *src, + size_t n, + grpc_slice_buffer *dst); /* move the first n bytes of src into dst (copying them) */ GPRAPI void grpc_slice_buffer_move_first_into_buffer(grpc_exec_ctx *exec_ctx, grpc_slice_buffer *src, diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c index 10af2525313..87549b78f0e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c @@ -98,7 +98,7 @@ grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) { pb_encode(&sizestream, grpc_lb_v1_LoadBalanceRequest_fields, request); encoded_length = sizestream.bytes_written; - slice = grpc_slice_malloc(encoded_length); + slice = GRPC_SLICE_MALLOC(encoded_length); outputstream = pb_ostream_from_buffer(GRPC_SLICE_START_PTR(slice), encoded_length); GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v1_LoadBalanceRequest_fields, diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.c b/src/core/ext/transport/chttp2/transport/bin_decoder.c index 8c87de112eb..21bed18c9a7 100644 --- a/src/core/ext/transport/chttp2/transport/bin_decoder.c +++ b/src/core/ext/transport/chttp2/transport/bin_decoder.c @@ -169,7 +169,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx, } } } - output = grpc_slice_malloc(output_length); + output = GRPC_SLICE_MALLOC(output_length); ctx.input_cur = GRPC_SLICE_START_PTR(input); ctx.input_end = GRPC_SLICE_END_PTR(input); @@ -193,7 +193,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx, grpc_slice input, size_t output_length) { size_t input_length = GRPC_SLICE_LENGTH(input); - grpc_slice output = grpc_slice_malloc(output_length); + grpc_slice output = GRPC_SLICE_MALLOC(output_length); struct grpc_base64_decode_context ctx; // The length of a base64 string cannot be 4 * n + 1 diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.c b/src/core/ext/transport/chttp2/transport/bin_encoder.c index e301c073f37..3b8ab1f17aa 100644 --- a/src/core/ext/transport/chttp2/transport/bin_encoder.c +++ b/src/core/ext/transport/chttp2/transport/bin_encoder.c @@ -66,7 +66,7 @@ grpc_slice grpc_chttp2_base64_encode(grpc_slice input) { size_t input_triplets = input_length / 3; size_t tail_case = input_length % 3; size_t output_length = input_triplets * 4 + tail_xtra[tail_case]; - grpc_slice output = grpc_slice_malloc(output_length); + grpc_slice output = GRPC_SLICE_MALLOC(output_length); uint8_t *in = GRPC_SLICE_START_PTR(input); char *out = (char *)GRPC_SLICE_START_PTR(output); size_t i; @@ -119,7 +119,7 @@ grpc_slice grpc_chttp2_huffman_compress(grpc_slice input) { nbits += grpc_chttp2_huffsyms[*in].length; } - output = grpc_slice_malloc(nbits / 8 + (nbits % 8 != 0)); + output = GRPC_SLICE_MALLOC(nbits / 8 + (nbits % 8 != 0)); out = GRPC_SLICE_START_PTR(output); for (in = GRPC_SLICE_START_PTR(input); in != GRPC_SLICE_END_PTR(input); ++in) { @@ -184,7 +184,7 @@ grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) { size_t output_syms = input_triplets * 4 + tail_xtra[tail_case]; size_t max_output_bits = 11 * output_syms; size_t max_output_length = max_output_bits / 8 + (max_output_bits % 8 != 0); - grpc_slice output = grpc_slice_malloc(max_output_length); + grpc_slice output = GRPC_SLICE_MALLOC(max_output_length); uint8_t *in = GRPC_SLICE_START_PTR(input); uint8_t *start_out = GRPC_SLICE_START_PTR(output); huff_out out; diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index e2816b0e045..f7d78026b7b 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1906,7 +1906,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, the time we got around to sending this, so instead we ignore HPACK compression and just write the uncompressed bytes onto the wire. */ if (!s->sent_initial_metadata) { - http_status_hdr = grpc_slice_malloc(13); + http_status_hdr = GRPC_SLICE_MALLOC(13); p = GRPC_SLICE_START_PTR(http_status_hdr); *p++ = 0x00; *p++ = 7; @@ -1925,7 +1925,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, len += (uint32_t)GRPC_SLICE_LENGTH(http_status_hdr); } - status_hdr = grpc_slice_malloc(15 + (grpc_status >= 10)); + status_hdr = GRPC_SLICE_MALLOC(15 + (grpc_status >= 10)); p = GRPC_SLICE_START_PTR(status_hdr); *p++ = 0x00; /* literal header, not indexed */ *p++ = 11; /* len(grpc-status) */ @@ -1954,7 +1954,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, size_t msg_len = GRPC_SLICE_LENGTH(slice); GPR_ASSERT(msg_len <= UINT32_MAX); uint32_t msg_len_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)msg_len, 1); - message_pfx = grpc_slice_malloc(14 + msg_len_len); + message_pfx = GRPC_SLICE_MALLOC(14 + msg_len_len); p = GRPC_SLICE_START_PTR(message_pfx); *p++ = 0x00; /* literal header, not indexed */ *p++ = 12; /* len(grpc-message) */ @@ -1976,7 +1976,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx); len += (uint32_t)msg_len; - hdr = grpc_slice_malloc(9); + hdr = GRPC_SLICE_MALLOC(9); p = GRPC_SLICE_START_PTR(hdr); *p++ = (uint8_t)(len >> 16); *p++ = (uint8_t)(len >> 8); diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 6e9258ee7ee..e9cf5324b0c 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -123,7 +123,7 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, uint8_t *p; static const size_t header_size = 9; - hdr = grpc_slice_malloc(header_size); + hdr = GRPC_SLICE_MALLOC(header_size); p = GRPC_SLICE_START_PTR(hdr); GPR_ASSERT(write_bytes < (1 << 24)); *p++ = (uint8_t)(write_bytes >> 16); @@ -137,7 +137,7 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, *p++ = (uint8_t)(id); grpc_slice_buffer_add(outbuf, hdr); - grpc_slice_buffer_move_first(inbuf, write_bytes, outbuf); + grpc_slice_buffer_move_first_no_ref(inbuf, write_bytes, outbuf); stats->framing_bytes += header_size; stats->data_bytes += write_bytes; diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.c b/src/core/ext/transport/chttp2/transport/frame_goaway.c index 001271dd228..0f1c8b0772f 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.c +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.c @@ -163,7 +163,7 @@ grpc_error *grpc_chttp2_goaway_parser_parse(grpc_exec_ctx *exec_ctx, void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, grpc_slice debug_data, grpc_slice_buffer *slice_buffer) { - grpc_slice header = grpc_slice_malloc(9 + 4 + 4); + grpc_slice header = GRPC_SLICE_MALLOC(9 + 4 + 4); uint8_t *p = GRPC_SLICE_START_PTR(header); uint32_t frame_length; GPR_ASSERT(GRPC_SLICE_LENGTH(debug_data) < UINT32_MAX - 4 - 4); diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.c b/src/core/ext/transport/chttp2/transport/frame_ping.c index 6016e43127c..f09ca607397 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.c +++ b/src/core/ext/transport/chttp2/transport/frame_ping.c @@ -43,7 +43,7 @@ static bool g_disable_ping_ack = false; grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint64_t opaque_8bytes) { - grpc_slice slice = grpc_slice_malloc(9 + 8); + grpc_slice slice = GRPC_SLICE_MALLOC(9 + 8); uint8_t *p = GRPC_SLICE_START_PTR(slice); *p++ = 0; 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 225f15c77c9..e0caa50e92e 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c @@ -44,7 +44,7 @@ grpc_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code, grpc_transport_one_way_stats *stats) { static const size_t frame_size = 13; - grpc_slice slice = grpc_slice_malloc(frame_size); + grpc_slice slice = GRPC_SLICE_MALLOC(frame_size); stats->framing_bytes += frame_size; uint8_t *p = GRPC_SLICE_START_PTR(slice); diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.c b/src/core/ext/transport/chttp2/transport/frame_settings.c index 16881c0707a..2a2986301d2 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.c +++ b/src/core/ext/transport/chttp2/transport/frame_settings.c @@ -93,7 +93,7 @@ grpc_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new, n += (new[i] != old[i] || (force_mask & (1u << i)) != 0); } - output = grpc_slice_malloc(9 + 6 * n); + output = GRPC_SLICE_MALLOC(9 + 6 * n); p = fill_header(GRPC_SLICE_START_PTR(output), 6 * n, 0); for (i = 0; i < count; i++) { @@ -115,7 +115,7 @@ grpc_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new, } grpc_slice grpc_chttp2_settings_ack_create(void) { - grpc_slice output = grpc_slice_malloc(9); + grpc_slice output = GRPC_SLICE_MALLOC(9); fill_header(GRPC_SLICE_START_PTR(output), 0, GRPC_CHTTP2_FLAG_ACK); return output; } diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.c b/src/core/ext/transport/chttp2/transport/frame_window_update.c index b76b6f6f477..8ed72dddca0 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.c +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.c @@ -41,7 +41,7 @@ grpc_slice grpc_chttp2_window_update_create( uint32_t id, uint32_t window_update, grpc_transport_one_way_stats *stats) { static const size_t frame_size = 13; - grpc_slice slice = grpc_slice_malloc(frame_size); + grpc_slice slice = GRPC_SLICE_MALLOC(frame_size); stats->header_bytes += frame_size; uint8_t *p = GRPC_SLICE_START_PTR(slice); diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c index 84586cd9988..b9b0f5cab0e 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c @@ -122,7 +122,7 @@ static void finish_frame(framer_state *st, int is_header_boundary, output before beginning */ static void begin_frame(framer_state *st) { st->header_idx = - grpc_slice_buffer_add_indexed(st->output, grpc_slice_malloc(9)); + grpc_slice_buffer_add_indexed(st->output, GRPC_SLICE_MALLOC(9)); st->output_length_at_start_of_frame = st->output->length; } diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 0b9189558f8..c0b09e752ca 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -1165,7 +1165,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx, } else if (stream_state->rs.remaining_bytes == 0) { CRONET_LOG(GPR_DEBUG, "read operation complete"); grpc_slice read_data_slice = - grpc_slice_malloc((uint32_t)stream_state->rs.length_field); + GRPC_SLICE_MALLOC((uint32_t)stream_state->rs.length_field); uint8_t *dst_p = GRPC_SLICE_START_PTR(read_data_slice); memcpy(dst_p, stream_state->rs.read_buffer, (size_t)stream_state->rs.length_field); diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 4e47c5c658f..570ec8608ba 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -312,7 +312,7 @@ static grpc_error *hc_mutate_op(grpc_exec_ctx *exec_ctx, op->payload->send_message.send_message->length, k_url_safe, k_multi_line); estimated_len += 1; /* for the trailing 0 */ - grpc_slice path_with_query_slice = grpc_slice_malloc(estimated_len); + grpc_slice path_with_query_slice = GRPC_SLICE_MALLOC(estimated_len); /* memcopy individual pieces into this slice */ uint8_t *write_ptr = diff --git a/src/core/lib/compression/message_compress.c b/src/core/lib/compression/message_compress.c index 49beb953b00..fd3d1e6fcc0 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/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c index f74aa687936..bdd4dd07afc 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/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c index 24da949e486..0d5c7432c64 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/slice/b64.c b/src/core/lib/slice/b64.c index 2007cc48109..d9091646e06 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 c76c58d371e..a77c69763f1 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 1cddf062cd4..8896f1dfd3f 100644 --- a/src/core/lib/slice/slice.c +++ b/src/core/lib/slice/slice.c @@ -197,7 +197,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) { - grpc_slice slice = grpc_slice_malloc(length); + grpc_slice slice = GRPC_SLICE_MALLOC(length); memcpy(GRPC_SLICE_START_PTR(slice), source, length); return slice; } @@ -227,35 +227,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; @@ -341,6 +348,40 @@ grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) { return tail; } +grpc_slice grpc_slice_split_tail_no_ref(grpc_slice *source, size_t split) { + grpc_slice tail; + + if (source->refcount == NULL) { + /* inlined data, copy it out */ + GPR_ASSERT(source->data.inlined.length >= split); + tail.refcount = NULL; + tail.data.inlined.length = (uint8_t)(source->data.inlined.length - split); + memcpy(tail.data.inlined.bytes, source->data.inlined.bytes + split, + tail.data.inlined.length); + source->data.inlined.length = (uint8_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)) { + /* 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); + } else { + /* Build the result */ + tail.refcount = &noop_refcount; + /* 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_head(grpc_slice *source, size_t split) { grpc_slice head; @@ -457,7 +498,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 c96b9c3b281..a13941e5ac8 100644 --- a/src/core/lib/slice/slice_buffer.c +++ b/src/core/lib/slice/slice_buffer.c @@ -255,14 +255,47 @@ void grpc_slice_buffer_move_into(grpc_slice_buffer *src, void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n, grpc_slice_buffer *dst) { + 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); + if (n > slice_len) { + grpc_slice_buffer_add(dst, slice); + n -= slice_len; + } 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)); + GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n); + grpc_slice_buffer_add(dst, slice); + break; + } + } + GPR_ASSERT(dst->length == output_len); + GPR_ASSERT(src->length == new_input_len); + GPR_ASSERT(src->count > 0); +} + +void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer *src, size_t n, + grpc_slice_buffer *dst) { 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); @@ -273,7 +306,8 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n, grpc_slice_buffer_add(dst, slice); break; } else { /* n < slice_len */ - grpc_slice_buffer_undo_take_first(src, grpc_slice_split_tail(&slice, n)); + grpc_slice_buffer_undo_take_first( + src, grpc_slice_split_tail_no_ref(&slice, n)); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n); grpc_slice_buffer_add(dst, slice); break; diff --git a/src/core/lib/surface/byte_buffer_reader.c b/src/core/lib/surface/byte_buffer_reader.c index 1a6ccdaddb6..539b0142783 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; From 255ea13aa381f905b88a0816a0a29ee0315d251f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Apr 2017 17:18:56 -0700 Subject: [PATCH 10/21] Reduce duplication --- include/grpc/slice.h | 7 +++-- src/core/lib/slice/slice.c | 47 ++++++++----------------------- src/core/lib/slice/slice_buffer.c | 43 ++++++++-------------------- 3 files changed, 27 insertions(+), 70 deletions(-) diff --git a/include/grpc/slice.h b/include/grpc/slice.h index 4dce6da9155..fe6379c867d 100644 --- a/include/grpc/slice.h +++ b/include/grpc/slice.h @@ -124,8 +124,11 @@ GPRAPI grpc_slice grpc_slice_sub_no_ref(grpc_slice s, size_t begin, size_t end); Requires s intialized, split <= s.length */ GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice *s, size_t split); -/* The same as grpc_slice_split_tail, but without altering refcounts */ -GPRAPI grpc_slice grpc_slice_split_tail_no_ref(grpc_slice *s, size_t split); +/* The same as grpc_slice_split_tail, but with an option to skip altering + * refcounts (grpc_slice_split_tail_maybe_ref(..., true) is equivalent to + * grpc_slice_split_tail(...)) */ +GPRAPI grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *s, size_t split, + bool inc_refs); /* Splits s into two: modifies s to be s[split:s.length], and returns a new slice, sharing a refcount with s, that contains s[0:split]. diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c index 8896f1dfd3f..285218837ac 100644 --- a/src/core/lib/slice/slice.c +++ b/src/core/lib/slice/slice.c @@ -312,7 +312,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, + bool incref) { grpc_slice tail; if (source->refcount == NULL) { @@ -334,9 +335,13 @@ grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) { tail_length); } else { /* Build the result */ - tail.refcount = source->refcount->sub_refcount; - /* Bump the refcount */ - tail.refcount->vtable->ref(tail.refcount); + if (incref) { + tail.refcount = source->refcount->sub_refcount; + /* Bump the refcount */ + tail.refcount->vtable->ref(tail.refcount); + } else { + tail.refcount = &noop_refcount; + } /* Point into the source array */ tail.data.refcounted.bytes = source->data.refcounted.bytes + split; tail.data.refcounted.length = tail_length; @@ -348,38 +353,8 @@ grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) { return tail; } -grpc_slice grpc_slice_split_tail_no_ref(grpc_slice *source, size_t split) { - grpc_slice tail; - - if (source->refcount == NULL) { - /* inlined data, copy it out */ - GPR_ASSERT(source->data.inlined.length >= split); - tail.refcount = NULL; - tail.data.inlined.length = (uint8_t)(source->data.inlined.length - split); - memcpy(tail.data.inlined.bytes, source->data.inlined.bytes + split, - tail.data.inlined.length); - source->data.inlined.length = (uint8_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)) { - /* 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); - } else { - /* Build the result */ - tail.refcount = &noop_refcount; - /* 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, true); } grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) { diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c index a13941e5ac8..5a4b434d28c 100644 --- a/src/core/lib/slice/slice_buffer.c +++ b/src/core/lib/slice/slice_buffer.c @@ -253,8 +253,9 @@ 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) { +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); @@ -274,7 +275,8 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n, grpc_slice_buffer_add(dst, slice); break; } else { /* n < slice_len */ - grpc_slice_buffer_undo_take_first(src, grpc_slice_split_tail(&slice, n)); + grpc_slice_buffer_undo_take_first( + src, grpc_slice_split_tail_maybe_ref(&slice, n, incref)); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n); grpc_slice_buffer_add(dst, slice); break; @@ -285,37 +287,14 @@ 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) { - 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); - if (n > slice_len) { - grpc_slice_buffer_add(dst, slice); - n -= slice_len; - } 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_no_ref(&slice, n)); - GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n); - grpc_slice_buffer_add(dst, slice); - break; - } - } - GPR_ASSERT(dst->length == output_len); - GPR_ASSERT(src->length == new_input_len); - GPR_ASSERT(src->count > 0); + slice_buffer_move_first_maybe_ref(src, n, dst, false); } void grpc_slice_buffer_move_first_into_buffer(grpc_exec_ctx *exec_ctx, From a3583b22eaf5448daff914a786d1e5214fe9aaec Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 13 Apr 2017 06:42:47 -0700 Subject: [PATCH 11/21] Fix compilation, add a check for no slow usages of grpc_slice_malloc --- include/grpc/slice.h | 2 +- src/core/lib/slice/slice.c | 2 +- tools/run_tests/sanity/core_banned_functions.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/grpc/slice.h b/include/grpc/slice.h index fe6379c867d..86a455b42c2 100644 --- a/include/grpc/slice.h +++ b/include/grpc/slice.h @@ -128,7 +128,7 @@ GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice *s, size_t split); * refcounts (grpc_slice_split_tail_maybe_ref(..., true) is equivalent to * grpc_slice_split_tail(...)) */ GPRAPI grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *s, size_t split, - bool inc_refs); + int inc_refs); /* Splits s into two: modifies s to be s[split:s.length], and returns a new slice, sharing a refcount with s, that contains s[0:split]. diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c index 285218837ac..e3d030235c8 100644 --- a/src/core/lib/slice/slice.c +++ b/src/core/lib/slice/slice.c @@ -313,7 +313,7 @@ grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) { } grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *source, size_t split, - bool incref) { + int incref) { grpc_slice tail; if (source->refcount == NULL) { diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index c3c3cbec767..2387c5f1da0 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -50,6 +50,7 @@ BANNED_EXCEPT = { 'grpc_os_error(': ['src/core/lib/iomgr/error.c'], 'grpc_wsa_error(': ['src/core/lib/iomgr/error.c'], 'grpc_log_if_error(': ['src/core/lib/iomgr/error.c'], + 'grpc_slice_malloc(': ['src/core/lib/slice/slice.c'], } errors = 0 From 0d23d8954f2ee9b809d21ec4e156b2347c8c340c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 20 Apr 2017 14:46:37 -0700 Subject: [PATCH 12/21] Add flexibility on *which* slice gets reffed Use it to ensure that sb_move_first acts predictably --- include/grpc/slice.h | 8 +++++++- src/core/lib/slice/slice.c | 30 ++++++++++++++++++++---------- src/core/lib/slice/slice_buffer.c | 10 ++++++++-- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/include/grpc/slice.h b/include/grpc/slice.h index d65bde49ee6..039347f17e3 100644 --- a/include/grpc/slice.h +++ b/include/grpc/slice.h @@ -124,11 +124,17 @@ GPRAPI grpc_slice grpc_slice_sub_no_ref(grpc_slice s, size_t begin, size_t end); Requires s intialized, split <= s.length */ GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice *s, size_t split); +typedef enum { + GRPC_SLICE_REF_TAIL = 1, + GRPC_SLICE_REF_HEAD = 2, + GRPC_SLICE_REF_BOTH = 1 + 2 +} grpc_slice_ref_whom; + /* The same as grpc_slice_split_tail, but with an option to skip altering * refcounts (grpc_slice_split_tail_maybe_ref(..., true) is equivalent to * grpc_slice_split_tail(...)) */ GPRAPI grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *s, size_t split, - int inc_refs); + grpc_slice_ref_whom ref_whom); /* Splits s into two: modifies s to be s[split:s.length], and returns a new slice, sharing a refcount with s, that contains s[0:split]. diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c index 219d1a4efcf..9e69b443fe1 100644 --- a/src/core/lib/slice/slice.c +++ b/src/core/lib/slice/slice.c @@ -314,7 +314,7 @@ grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) { } grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *source, size_t split, - int incref) { + grpc_slice_ref_whom ref_whom) { grpc_slice tail; if (source->refcount == NULL) { @@ -328,26 +328,36 @@ grpc_slice grpc_slice_split_tail_maybe_ref(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 */ - if (incref) { - tail.refcount = source->refcount->sub_refcount; - /* Bump the refcount */ - tail.refcount->vtable->ref(tail.refcount); - } else { - tail.refcount = &noop_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; } @@ -355,7 +365,7 @@ grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *source, size_t split, } grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) { - return grpc_slice_split_tail_maybe_ref(source, split, true); + 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) { diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c index 5a4b434d28c..e8d41ca0f7d 100644 --- a/src/core/lib/slice/slice_buffer.c +++ b/src/core/lib/slice/slice_buffer.c @@ -274,12 +274,18 @@ static void slice_buffer_move_first_maybe_ref(grpc_slice_buffer *src, size_t n, } else if (n == slice_len) { grpc_slice_buffer_add(dst, slice); break; - } else { /* n < slice_len */ + } else if (incref) { /* n < slice_len */ grpc_slice_buffer_undo_take_first( - src, grpc_slice_split_tail_maybe_ref(&slice, n, incref)); + 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); From 85bf34a4a8d0b8299ddda1b1abca401d8f2dd4a6 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 21 Apr 2017 16:14:59 -0700 Subject: [PATCH 13/21] Copy slices for in-process transports: its no longer safe to just ref --- include/grpc/slice.h | 3 +++ src/core/lib/slice/slice.c | 7 +++++++ test/core/util/passthru_endpoint.c | 4 ++-- test/core/util/trickle_endpoint.c | 7 +++---- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/include/grpc/slice.h b/include/grpc/slice.h index 039347f17e3..9c4b158ae8d 100644 --- a/include/grpc/slice.h +++ b/include/grpc/slice.h @@ -53,6 +53,9 @@ GPRAPI grpc_slice grpc_slice_ref(grpc_slice s); where dest!=NULL , then (*dest)(start, len). Requires s initialized. */ GPRAPI void grpc_slice_unref(grpc_slice s); +/* Copy slice - create a new slice that contains the same data as s */ +GPRAPI grpc_slice grpc_slice_copy(grpc_slice s); + /* Create a slice pointing at some data. Calls malloc to allocate a refcount for the object, and arranges that destroy will be called with the pointer passed in at destruction. */ diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c index 9e69b443fe1..b90738fd1aa 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); diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c index 121567fc0d2..ad718c75d1f 100644 --- a/test/core/util/passthru_endpoint.c +++ b/test/core/util/passthru_endpoint.c @@ -102,13 +102,13 @@ static void me_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Endpoint already shutdown"); } else if (m->on_read != NULL) { for (size_t i = 0; i < slices->count; i++) { - grpc_slice_buffer_add(m->on_read_out, grpc_slice_ref(slices->slices[i])); + grpc_slice_buffer_add(m->on_read_out, grpc_slice_copy(slices->slices[i])); } grpc_closure_sched(exec_ctx, m->on_read, GRPC_ERROR_NONE); m->on_read = NULL; } else { for (size_t i = 0; i < slices->count; i++) { - grpc_slice_buffer_add(&m->read_buffer, grpc_slice_ref(slices->slices[i])); + grpc_slice_buffer_add(&m->read_buffer, grpc_slice_copy(slices->slices[i])); } } gpr_mu_unlock(&m->parent->mu); diff --git a/test/core/util/trickle_endpoint.c b/test/core/util/trickle_endpoint.c index 0848147158a..66f30c8e65d 100644 --- a/test/core/util/trickle_endpoint.c +++ b/test/core/util/trickle_endpoint.c @@ -66,14 +66,13 @@ static void te_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, static void te_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, grpc_slice_buffer *slices, grpc_closure *cb) { trickle_endpoint *te = (trickle_endpoint *)ep; - for (size_t i = 0; i < slices->count; i++) { - grpc_slice_ref_internal(slices->slices[i]); - } gpr_mu_lock(&te->mu); if (te->write_buffer.length == 0) { te->last_write = gpr_now(GPR_CLOCK_MONOTONIC); } - grpc_slice_buffer_addn(&te->write_buffer, slices->slices, slices->count); + for (size_t i = 0; i < slices->count; i++) { + grpc_slice_buffer_add(&te->write_buffer, grpc_slice_copy(slices->slices[i])); + } grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_REF(te->error)); gpr_mu_unlock(&te->mu); } From 1dd609b3c1a3ebb74cd0410d425ace362c66c964 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 24 Apr 2017 12:56:26 +0200 Subject: [PATCH 14/21] fix C++ distribtests --- test/distrib/cpp/run_distrib_test.sh | 9 ++------ .../artifacts/distribtest_targets.py | 22 +++++++++++++------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/test/distrib/cpp/run_distrib_test.sh b/test/distrib/cpp/run_distrib_test.sh index 15fbf281074..4728e32f065 100755 --- a/test/distrib/cpp/run_distrib_test.sh +++ b/test/distrib/cpp/run_distrib_test.sh @@ -30,13 +30,8 @@ set -ex -git clone $EXTERNAL_GIT_ROOT -# clone gRPC submodules, use data from locally cloned submodules where possible -(cd ${EXTERNAL_GIT_ROOT} && git submodule foreach 'cd /var/local/git/grpc \ -&& git submodule update --init --reference ${EXTERNAL_GIT_ROOT}/${name} \ -${name}') - -cd grpc +# change to grpc repo root +cd $(dirname $0)/../../.. cd third_party/protobuf && ./autogen.sh && \ ./configure && make -j4 && make check && make install && ldconfig diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index 90bbde83cf4..097fd2d8b5e 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -38,11 +38,14 @@ import python_utils.jobset as jobset def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={}, - flake_retries=0, timeout_retries=0): + flake_retries=0, timeout_retries=0, + copy_rel_path=None): """Creates jobspec for a task running under docker.""" environ = environ.copy() environ['RUN_COMMAND'] = shell_command - environ['RELATIVE_COPY_PATH'] = 'test/distrib' + # the entire repo will be cloned if copy_rel_path is not set. + if copy_rel_path: + environ['RELATIVE_COPY_PATH'] = copy_rel_path docker_args=[] for k,v in environ.items(): @@ -102,7 +105,8 @@ class CSharpDistribTest(object): 'tools/dockerfile/distribtest/csharp_%s_%s' % ( self.docker_suffix, self.arch), - 'test/distrib/csharp/run_distrib_test%s.sh' % self.script_suffix) + 'test/distrib/csharp/run_distrib_test%s.sh' % self.script_suffix, + copy_rel_path='test/distrib') elif self.platform == 'macos': return create_jobspec(self.name, ['test/distrib/csharp/run_distrib_test%s.sh' % self.script_suffix], @@ -151,7 +155,8 @@ class NodeDistribTest(object): self.arch), '%s test/distrib/node/run_distrib_test.sh %s' % ( linux32, - self.node_version)) + self.node_version), + copy_rel_path='test/distrib') elif self.platform == 'macos': return create_jobspec(self.name, ['test/distrib/node/run_distrib_test.sh', @@ -185,7 +190,8 @@ class PythonDistribTest(object): 'tools/dockerfile/distribtest/python_%s_%s' % ( self.docker_suffix, self.arch), - 'test/distrib/python/run_distrib_test.sh') + 'test/distrib/python/run_distrib_test.sh', + copy_rel_path='test/distrib') def __str__(self): return self.name @@ -212,7 +218,8 @@ class RubyDistribTest(object): 'tools/dockerfile/distribtest/ruby_%s_%s' % ( self.docker_suffix, self.arch), - 'test/distrib/ruby/run_distrib_test.sh') + 'test/distrib/ruby/run_distrib_test.sh', + copy_rel_path='test/distrib') def __str__(self): return self.name @@ -237,7 +244,8 @@ class PHPDistribTest(object): 'tools/dockerfile/distribtest/php_%s_%s' % ( self.docker_suffix, self.arch), - 'test/distrib/php/run_distrib_test.sh') + 'test/distrib/php/run_distrib_test.sh', + copy_rel_path='test/distrib') elif self.platform == 'macos': return create_jobspec(self.name, ['test/distrib/php/run_distrib_test.sh'], From e0e961aae70a3764d211de8f07610585db63daf2 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Mon, 24 Apr 2017 09:11:44 -0700 Subject: [PATCH 15/21] fix guard on src/core/tsi/transport_security_adapter.h --- memory_usage.csv | 1 + src/core/tsi/transport_security_adapter.h | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 memory_usage.csv diff --git a/memory_usage.csv b/memory_usage.csv new file mode 100644 index 00000000000..6eaf90f61fd --- /dev/null +++ b/memory_usage.csv @@ -0,0 +1 @@ +5678.136000,586484,4195801,5849.208667,205445,, diff --git a/src/core/tsi/transport_security_adapter.h b/src/core/tsi/transport_security_adapter.h index 686618b53b1..e4dc07515f1 100644 --- a/src/core/tsi/transport_security_adapter.h +++ b/src/core/tsi/transport_security_adapter.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_SRC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H -#define GRPC_SRC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H +#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H +#define GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H #include "src/core/tsi/transport_security_interface.h" @@ -59,4 +59,4 @@ tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter); } #endif -#endif // GRPC_SRC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H +#endif // GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H From f2263e14ca778e0a42d896ad5228c671fbb97aed Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Mon, 24 Apr 2017 15:32:03 -0700 Subject: [PATCH 16/21] fix guards in transport_security_adapter.h --- memory_usage.csv | 1 - src/core/tsi/transport_security_adapter.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 memory_usage.csv diff --git a/memory_usage.csv b/memory_usage.csv deleted file mode 100644 index 6eaf90f61fd..00000000000 --- a/memory_usage.csv +++ /dev/null @@ -1 +0,0 @@ -5678.136000,586484,4195801,5849.208667,205445,, diff --git a/src/core/tsi/transport_security_adapter.h b/src/core/tsi/transport_security_adapter.h index e4dc07515f1..400df2f11bd 100644 --- a/src/core/tsi/transport_security_adapter.h +++ b/src/core/tsi/transport_security_adapter.h @@ -59,4 +59,4 @@ tsi_handshaker *tsi_adapter_handshaker_get_wrapped(tsi_handshaker *adapter); } #endif -#endif // GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H +#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H */ From e38948a1cdd44554095ad8b277e86877dfda1301 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 26 Apr 2017 08:53:25 -0700 Subject: [PATCH 17/21] clang-format --- test/core/util/passthru_endpoint.c | 3 ++- test/core/util/trickle_endpoint.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c index ad718c75d1f..6400845d235 100644 --- a/test/core/util/passthru_endpoint.c +++ b/test/core/util/passthru_endpoint.c @@ -108,7 +108,8 @@ static void me_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, m->on_read = NULL; } else { for (size_t i = 0; i < slices->count; i++) { - grpc_slice_buffer_add(&m->read_buffer, grpc_slice_copy(slices->slices[i])); + grpc_slice_buffer_add(&m->read_buffer, + grpc_slice_copy(slices->slices[i])); } } gpr_mu_unlock(&m->parent->mu); diff --git a/test/core/util/trickle_endpoint.c b/test/core/util/trickle_endpoint.c index 66f30c8e65d..58ac59711be 100644 --- a/test/core/util/trickle_endpoint.c +++ b/test/core/util/trickle_endpoint.c @@ -71,7 +71,8 @@ static void te_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, te->last_write = gpr_now(GPR_CLOCK_MONOTONIC); } for (size_t i = 0; i < slices->count; i++) { - grpc_slice_buffer_add(&te->write_buffer, grpc_slice_copy(slices->slices[i])); + grpc_slice_buffer_add(&te->write_buffer, + grpc_slice_copy(slices->slices[i])); } grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_REF(te->error)); gpr_mu_unlock(&te->mu); From bb4046cd771344f69b3268a86c48b01cd34a921d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 26 Apr 2017 08:56:30 -0700 Subject: [PATCH 18/21] Regenerate projects --- grpc.def | 1 + src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 5 ++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/grpc.def b/grpc.def index 54f9609bc2a..8b64b37ff34 100644 --- a/grpc.def +++ b/grpc.def @@ -142,6 +142,7 @@ EXPORTS grpc_server_credentials_set_auth_metadata_processor grpc_slice_ref grpc_slice_unref + grpc_slice_copy grpc_slice_new grpc_slice_new_with_user_data grpc_slice_new_with_len diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index b6360f2d4c9..d11f7f6a78a 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -180,6 +180,7 @@ grpc_call_set_credentials_type grpc_call_set_credentials_import; grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import; grpc_slice_ref_type grpc_slice_ref_import; grpc_slice_unref_type grpc_slice_unref_import; +grpc_slice_copy_type grpc_slice_copy_import; grpc_slice_new_type grpc_slice_new_import; grpc_slice_new_with_user_data_type grpc_slice_new_with_user_data_import; grpc_slice_new_with_len_type grpc_slice_new_with_len_import; @@ -481,6 +482,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_server_credentials_set_auth_metadata_processor_import = (grpc_server_credentials_set_auth_metadata_processor_type) GetProcAddress(library, "grpc_server_credentials_set_auth_metadata_processor"); grpc_slice_ref_import = (grpc_slice_ref_type) GetProcAddress(library, "grpc_slice_ref"); grpc_slice_unref_import = (grpc_slice_unref_type) GetProcAddress(library, "grpc_slice_unref"); + grpc_slice_copy_import = (grpc_slice_copy_type) GetProcAddress(library, "grpc_slice_copy"); grpc_slice_new_import = (grpc_slice_new_type) GetProcAddress(library, "grpc_slice_new"); grpc_slice_new_with_user_data_import = (grpc_slice_new_with_user_data_type) GetProcAddress(library, "grpc_slice_new_with_user_data"); grpc_slice_new_with_len_import = (grpc_slice_new_with_len_type) GetProcAddress(library, "grpc_slice_new_with_len"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 539b7de9bd3..dc50b87baf2 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -491,6 +491,9 @@ extern grpc_slice_ref_type grpc_slice_ref_import; typedef void(*grpc_slice_unref_type)(grpc_slice s); extern grpc_slice_unref_type grpc_slice_unref_import; #define grpc_slice_unref grpc_slice_unref_import +typedef grpc_slice(*grpc_slice_copy_type)(grpc_slice s); +extern grpc_slice_copy_type grpc_slice_copy_import; +#define grpc_slice_copy grpc_slice_copy_import typedef grpc_slice(*grpc_slice_new_type)(void *p, size_t len, void (*destroy)(void *)); extern grpc_slice_new_type grpc_slice_new_import; #define grpc_slice_new grpc_slice_new_import @@ -530,7 +533,7 @@ extern grpc_slice_sub_no_ref_type grpc_slice_sub_no_ref_import; typedef grpc_slice(*grpc_slice_split_tail_type)(grpc_slice *s, size_t split); extern grpc_slice_split_tail_type grpc_slice_split_tail_import; #define grpc_slice_split_tail grpc_slice_split_tail_import -typedef grpc_slice(*grpc_slice_split_tail_maybe_ref_type)(grpc_slice *s, size_t split, int inc_refs); +typedef grpc_slice(*grpc_slice_split_tail_maybe_ref_type)(grpc_slice *s, size_t split, grpc_slice_ref_whom ref_whom); extern grpc_slice_split_tail_maybe_ref_type grpc_slice_split_tail_maybe_ref_import; #define grpc_slice_split_tail_maybe_ref grpc_slice_split_tail_maybe_ref_import typedef grpc_slice(*grpc_slice_split_head_type)(grpc_slice *s, size_t split); From 78ca0d1d57248e07eebb028e9fe2e587076d5fd1 Mon Sep 17 00:00:00 2001 From: Mahak Mukhi Date: Wed, 26 Apr 2017 13:39:46 -0700 Subject: [PATCH 19/21] Fix for recent cmake failure owing to gmock --- CMakeLists.txt | 243 +++++++++++++++++++++++++++++- templates/CMakeLists.txt.template | 13 +- 2 files changed, 252 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d7662031d1..1306884d706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -316,10 +316,11 @@ function(protobuf_generate_grpc_cpp) add_custom_command( OUTPUT "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" + "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" COMMAND ${_gRPC_PROTOBUF_PROTOC} - ARGS --grpc_out=${_gRPC_PROTO_GENS_DIR} + ARGS --grpc_out=generate_mock_code=true:${_gRPC_PROTO_GENS_DIR} --cpp_out=${_gRPC_PROTO_GENS_DIR} --plugin=protoc-gen-grpc=$ ${_protobuf_include_path} @@ -329,7 +330,7 @@ function(protobuf_generate_grpc_cpp) COMMENT "Running gRPC C++ protocol buffer compiler on ${FIL}" VERBATIM) - set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE) + set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE) endforeach() endfunction() @@ -3008,6 +3009,8 @@ target_include_directories(grpc++_proto_reflection_desc_db PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -3127,6 +3130,8 @@ target_include_directories(grpc++_test_config PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -3152,6 +3157,7 @@ add_library(grpc++_test_util ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_mock.grpc.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h @@ -3204,6 +3210,8 @@ target_include_directories(grpc++_test_util PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -3630,6 +3638,8 @@ target_include_directories(grpc_benchmark PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -3689,6 +3699,8 @@ target_include_directories(grpc_cli_libs PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -3828,6 +3840,8 @@ target_include_directories(http2_client_main PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -3883,6 +3897,8 @@ target_include_directories(interop_client_helper PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -3953,6 +3969,8 @@ target_include_directories(interop_client_main PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -4004,6 +4022,8 @@ target_include_directories(interop_server_helper PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -4073,6 +4093,8 @@ target_include_directories(interop_server_lib PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -4124,6 +4146,8 @@ target_include_directories(interop_server_main PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -4212,6 +4236,8 @@ target_include_directories(qps PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -8767,6 +8793,7 @@ if (gRPC_BUILD_TESTS) add_executable(alarm_cpp_test test/cpp/common/alarm_cpp_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -8785,6 +8812,8 @@ target_include_directories(alarm_cpp_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -8806,6 +8835,7 @@ if (gRPC_BUILD_TESTS) add_executable(async_end2end_test test/cpp/end2end/async_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -8824,6 +8854,8 @@ target_include_directories(async_end2end_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -8845,6 +8877,7 @@ if (gRPC_BUILD_TESTS) add_executable(auth_property_iterator_test test/cpp/common/auth_property_iterator_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -8863,6 +8896,8 @@ target_include_directories(auth_property_iterator_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -8885,6 +8920,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_arena test/cpp/microbenchmarks/bm_arena.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -8903,6 +8939,8 @@ target_include_directories(bm_arena PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -8928,6 +8966,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_call_create test/cpp/microbenchmarks/bm_call_create.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -8946,6 +8985,8 @@ target_include_directories(bm_call_create PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -8971,6 +9012,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_chttp2_hpack test/cpp/microbenchmarks/bm_chttp2_hpack.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -8989,6 +9031,8 @@ target_include_directories(bm_chttp2_hpack PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9014,6 +9058,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_chttp2_transport test/cpp/microbenchmarks/bm_chttp2_transport.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9032,6 +9077,8 @@ target_include_directories(bm_chttp2_transport PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9057,6 +9104,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_closure test/cpp/microbenchmarks/bm_closure.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9075,6 +9123,8 @@ target_include_directories(bm_closure PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9100,6 +9150,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_cq test/cpp/microbenchmarks/bm_cq.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9118,6 +9169,8 @@ target_include_directories(bm_cq PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9143,6 +9196,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_cq_multiple_threads test/cpp/microbenchmarks/bm_cq_multiple_threads.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9161,6 +9215,8 @@ target_include_directories(bm_cq_multiple_threads PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9186,6 +9242,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_error test/cpp/microbenchmarks/bm_error.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9204,6 +9261,8 @@ target_include_directories(bm_error PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9229,6 +9288,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_fullstack_streaming_ping_pong test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9247,6 +9307,8 @@ target_include_directories(bm_fullstack_streaming_ping_pong PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9272,6 +9334,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_fullstack_streaming_pump test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9290,6 +9353,8 @@ target_include_directories(bm_fullstack_streaming_pump PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9315,6 +9380,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_fullstack_trickle test/cpp/microbenchmarks/bm_fullstack_trickle.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9333,6 +9399,8 @@ target_include_directories(bm_fullstack_trickle PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9358,6 +9426,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_fullstack_unary_ping_pong test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9376,6 +9445,8 @@ target_include_directories(bm_fullstack_unary_ping_pong PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9401,6 +9472,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_metadata test/cpp/microbenchmarks/bm_metadata.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9419,6 +9491,8 @@ target_include_directories(bm_metadata PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9444,6 +9518,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(bm_pollset test/cpp/microbenchmarks/bm_pollset.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9462,6 +9537,8 @@ target_include_directories(bm_pollset PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9486,6 +9563,7 @@ if (gRPC_BUILD_TESTS) add_executable(channel_arguments_test test/cpp/common/channel_arguments_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9504,6 +9582,8 @@ target_include_directories(channel_arguments_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9522,6 +9602,7 @@ if (gRPC_BUILD_TESTS) add_executable(channel_filter_test test/cpp/common/channel_filter_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9540,6 +9621,8 @@ target_include_directories(channel_filter_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9558,6 +9641,7 @@ if (gRPC_BUILD_TESTS) add_executable(cli_call_test test/cpp/util/cli_call_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9576,6 +9660,8 @@ target_include_directories(cli_call_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9599,6 +9685,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(client_crash_test test/cpp/end2end/client_crash_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9617,6 +9704,8 @@ target_include_directories(client_crash_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9639,6 +9728,7 @@ if (gRPC_BUILD_TESTS) add_executable(client_crash_test_server test/cpp/end2end/client_crash_test_server.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9657,6 +9747,8 @@ target_include_directories(client_crash_test_server PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9698,6 +9790,7 @@ add_executable(codegen_test_full ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.h test/cpp/codegen/codegen_test_full.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -9731,6 +9824,8 @@ target_include_directories(codegen_test_full PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9770,6 +9865,7 @@ add_executable(codegen_test_minimal test/cpp/codegen/codegen_test_minimal.cc src/cpp/codegen/codegen_init.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -9803,6 +9899,8 @@ target_include_directories(codegen_test_minimal PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9820,6 +9918,7 @@ if (gRPC_BUILD_TESTS) add_executable(credentials_test test/cpp/client/credentials_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9838,6 +9937,8 @@ target_include_directories(credentials_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9856,6 +9957,7 @@ if (gRPC_BUILD_TESTS) add_executable(cxx_byte_buffer_test test/cpp/util/byte_buffer_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9874,6 +9976,8 @@ target_include_directories(cxx_byte_buffer_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9894,6 +9998,7 @@ if (gRPC_BUILD_TESTS) add_executable(cxx_slice_test test/cpp/util/slice_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9912,6 +10017,8 @@ target_include_directories(cxx_slice_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9932,6 +10039,7 @@ if (gRPC_BUILD_TESTS) add_executable(cxx_string_ref_test test/cpp/util/string_ref_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9950,6 +10058,8 @@ target_include_directories(cxx_string_ref_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -9966,6 +10076,7 @@ if (gRPC_BUILD_TESTS) add_executable(cxx_time_test test/cpp/util/time_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -9984,6 +10095,8 @@ target_include_directories(cxx_time_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10004,6 +10117,7 @@ if (gRPC_BUILD_TESTS) add_executable(end2end_test test/cpp/end2end/end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10022,6 +10136,8 @@ target_include_directories(end2end_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10047,6 +10163,7 @@ add_executable(error_details_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h test/cpp/util/error_details_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -10068,6 +10185,8 @@ target_include_directories(error_details_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10085,6 +10204,7 @@ if (gRPC_BUILD_TESTS) add_executable(filter_end2end_test test/cpp/end2end/filter_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10103,6 +10223,8 @@ target_include_directories(filter_end2end_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10124,6 +10246,7 @@ if (gRPC_BUILD_TESTS) add_executable(generic_end2end_test test/cpp/end2end/generic_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10142,6 +10265,8 @@ target_include_directories(generic_end2end_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10167,6 +10292,7 @@ add_executable(golden_file_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/compiler_test.grpc.pb.h test/cpp/codegen/golden_file_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -10188,6 +10314,8 @@ target_include_directories(golden_file_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10206,6 +10334,7 @@ if (gRPC_BUILD_TESTS) add_executable(grpc_cli test/cpp/util/grpc_cli.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10224,6 +10353,8 @@ target_include_directories(grpc_cli PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10519,6 +10650,7 @@ add_executable(grpc_tool_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h test/cpp/util/grpc_tool_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -10543,6 +10675,8 @@ target_include_directories(grpc_tool_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10571,6 +10705,7 @@ add_executable(grpclb_api_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h test/cpp/grpclb/grpclb_api_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -10592,6 +10727,8 @@ target_include_directories(grpclb_api_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10615,6 +10752,7 @@ add_executable(grpclb_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h test/cpp/grpclb/grpclb_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -10636,6 +10774,8 @@ target_include_directories(grpclb_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10657,6 +10797,7 @@ if (gRPC_BUILD_TESTS) add_executable(health_service_end2end_test test/cpp/end2end/health_service_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10675,6 +10816,8 @@ target_include_directories(health_service_end2end_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10696,6 +10839,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(http2_client third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10714,6 +10858,8 @@ target_include_directories(http2_client PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10736,6 +10882,7 @@ if (gRPC_BUILD_TESTS) add_executable(hybrid_end2end_test test/cpp/end2end/hybrid_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10754,6 +10901,8 @@ target_include_directories(hybrid_end2end_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10775,6 +10924,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(interop_client third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10793,6 +10943,8 @@ target_include_directories(interop_client PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10818,6 +10970,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(interop_server third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10836,6 +10989,8 @@ target_include_directories(interop_server PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10863,6 +11018,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(interop_test test/cpp/interop/interop_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10881,6 +11037,8 @@ target_include_directories(interop_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10903,6 +11061,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(json_run_localhost test/cpp/qps/json_run_localhost.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -10921,6 +11080,8 @@ target_include_directories(json_run_localhost PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10948,6 +11109,7 @@ add_executable(metrics_client ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/metrics.grpc.pb.h test/cpp/interop/metrics_client.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -10969,6 +11131,8 @@ target_include_directories(metrics_client PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -10988,6 +11152,7 @@ if (gRPC_BUILD_TESTS) add_executable(mock_test test/cpp/end2end/mock_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11006,6 +11171,8 @@ target_include_directories(mock_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11027,6 +11194,7 @@ if (gRPC_BUILD_TESTS) add_executable(noop-benchmark test/cpp/microbenchmarks/noop-benchmark.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11045,6 +11213,8 @@ target_include_directories(noop-benchmark PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11061,6 +11231,7 @@ if (gRPC_BUILD_TESTS) add_executable(proto_server_reflection_test test/cpp/end2end/proto_server_reflection_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11079,6 +11250,8 @@ target_include_directories(proto_server_reflection_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11102,6 +11275,7 @@ if (gRPC_BUILD_TESTS) add_executable(proto_utils_test test/cpp/codegen/proto_utils_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11120,6 +11294,8 @@ target_include_directories(proto_utils_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11138,6 +11314,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(qps_interarrival_test test/cpp/qps/qps_interarrival_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11156,6 +11333,8 @@ target_include_directories(qps_interarrival_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11179,6 +11358,7 @@ if (gRPC_BUILD_TESTS) add_executable(qps_json_driver test/cpp/qps/qps_json_driver.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11197,6 +11377,8 @@ target_include_directories(qps_json_driver PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11221,6 +11403,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(qps_openloop_test test/cpp/qps/qps_openloop_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11239,6 +11422,8 @@ target_include_directories(qps_openloop_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11263,6 +11448,7 @@ if (gRPC_BUILD_TESTS) add_executable(qps_worker test/cpp/qps/worker.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11281,6 +11467,8 @@ target_include_directories(qps_worker PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11316,6 +11504,7 @@ add_executable(reconnect_interop_client ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h test/cpp/interop/reconnect_interop_client.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -11343,6 +11532,8 @@ target_include_directories(reconnect_interop_client PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11377,6 +11568,7 @@ add_executable(reconnect_interop_server ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h test/cpp/interop/reconnect_interop_server.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -11404,6 +11596,8 @@ target_include_directories(reconnect_interop_server PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11428,6 +11622,7 @@ if (gRPC_BUILD_TESTS) add_executable(round_robin_end2end_test test/cpp/end2end/round_robin_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11446,6 +11641,8 @@ target_include_directories(round_robin_end2end_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11467,6 +11664,7 @@ if (gRPC_BUILD_TESTS) add_executable(secure_auth_context_test test/cpp/common/secure_auth_context_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11485,6 +11683,8 @@ target_include_directories(secure_auth_context_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11507,6 +11707,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(secure_sync_unary_ping_pong_test test/cpp/qps/secure_sync_unary_ping_pong_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11525,6 +11726,8 @@ target_include_directories(secure_sync_unary_ping_pong_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11548,6 +11751,7 @@ if (gRPC_BUILD_TESTS) add_executable(server_builder_plugin_test test/cpp/end2end/server_builder_plugin_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11566,6 +11770,8 @@ target_include_directories(server_builder_plugin_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11595,6 +11801,7 @@ add_executable(server_builder_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h test/cpp/server/server_builder_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -11619,6 +11826,8 @@ target_include_directories(server_builder_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11640,6 +11849,7 @@ if (gRPC_BUILD_TESTS) add_executable(server_context_test_spouse_test test/cpp/test/server_context_test_spouse_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11658,6 +11868,8 @@ target_include_directories(server_context_test_spouse_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11679,6 +11891,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(server_crash_test test/cpp/end2end/server_crash_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11697,6 +11910,8 @@ target_include_directories(server_crash_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11719,6 +11934,7 @@ if (gRPC_BUILD_TESTS) add_executable(server_crash_test_client test/cpp/end2end/server_crash_test_client.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11737,6 +11953,8 @@ target_include_directories(server_crash_test_client PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11758,6 +11976,7 @@ if (gRPC_BUILD_TESTS) add_executable(shutdown_test test/cpp/end2end/shutdown_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11776,6 +11995,8 @@ target_include_directories(shutdown_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11797,6 +12018,7 @@ if (gRPC_BUILD_TESTS) add_executable(status_test test/cpp/util/status_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11815,6 +12037,8 @@ target_include_directories(status_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11836,6 +12060,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(streaming_throughput_test test/cpp/end2end/streaming_throughput_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11854,6 +12079,8 @@ target_include_directories(streaming_throughput_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11895,6 +12122,7 @@ add_executable(stress_test test/cpp/interop/stress_test.cc test/cpp/util/metrics_server.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) protobuf_generate_grpc_cpp( @@ -11925,6 +12153,8 @@ target_include_directories(stress_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11947,6 +12177,7 @@ if (gRPC_BUILD_TESTS) add_executable(thread_manager_test test/cpp/thread_manager/thread_manager_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -11965,6 +12196,8 @@ target_include_directories(thread_manager_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -11984,6 +12217,7 @@ if (gRPC_BUILD_TESTS) add_executable(thread_stress_test test/cpp/end2end/thread_stress_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -12002,6 +12236,8 @@ target_include_directories(thread_stress_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) @@ -12024,6 +12260,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_executable(writes_per_rpc_test test/cpp/performance/writes_per_rpc_test.cc third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -12042,6 +12279,8 @@ target_include_directories(writes_per_rpc_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 88e518f1321..2252a7ea80a 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -361,10 +361,11 @@ add_custom_command( OUTPUT <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" + <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h" <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" COMMAND <%text>${_gRPC_PROTOBUF_PROTOC} - ARGS --grpc_out=<%text>${_gRPC_PROTO_GENS_DIR} + ARGS --grpc_out=<%text>generate_mock_code=true:${_gRPC_PROTO_GENS_DIR} --cpp_out=<%text>${_gRPC_PROTO_GENS_DIR} --plugin=protoc-gen-grpc=$ <%text>${_protobuf_include_path} @@ -374,7 +375,7 @@ COMMENT "Running gRPC C++ protocol buffer compiler on <%text>${FIL}" VERBATIM) - <%text>set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE) + <%text>set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE) endforeach() endfunction() @@ -475,6 +476,9 @@ ${proto_replace_ext(src, '.grpc.pb.cc')} ${proto_replace_ext(src, '.pb.h')} ${proto_replace_ext(src, '.grpc.pb.h')} + % if src in ["src/proto/grpc/testing/compiler_test.proto", "src/proto/grpc/testing/echo.proto"]: + ${proto_replace_ext(src, '_mock.grpc.pb.h')} + % endif % endif % endfor ) @@ -514,6 +518,8 @@ % if lib.build in ['test', 'private'] and lib.language == 'c++': PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock % endif % if lib.language == 'c++': PRIVATE <%text>${_gRPC_PROTO_GENS_DIR} @@ -557,6 +563,7 @@ % endfor % if tgt.build == 'test' and tgt.language == 'c++': third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc % endif ) @@ -584,6 +591,8 @@ % if tgt.build in ['test', 'private'] and tgt.language == 'c++': PRIVATE third_party/googletest/googletest/include PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock % endif % if tgt.language == 'c++': PRIVATE <%text>${_gRPC_PROTO_GENS_DIR} From 6ae9175690f26b21b2888c780821482074d4a1bb Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Wed, 26 Apr 2017 19:03:18 -0700 Subject: [PATCH 20/21] Update performance VM init script --- tools/gce/create_linux_performance_worker.sh | 4 +- tools/gce/linux_performance_worker_init.sh | 50 +++++++++++--------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/tools/gce/create_linux_performance_worker.sh b/tools/gce/create_linux_performance_worker.sh index 2c8cf0b96b3..68710e13b07 100755 --- a/tools/gce/create_linux_performance_worker.sh +++ b/tools/gce/create_linux_performance_worker.sh @@ -42,14 +42,14 @@ CLOUD_PROJECT=grpc-testing ZONE=us-central1-b # this zone allows 32core machines INSTANCE_NAME="${1:-grpc-performance-server1}" -MACHINE_TYPE=n1-standard-8 +MACHINE_TYPE=n1-standard-32 gcloud compute instances create $INSTANCE_NAME \ --project="$CLOUD_PROJECT" \ --zone "$ZONE" \ --machine-type $MACHINE_TYPE \ --image-project ubuntu-os-cloud \ - --image-family ubuntu-1604-lts \ + --image-family ubuntu-1610 \ --boot-disk-size 300 \ --scopes https://www.googleapis.com/auth/bigquery diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh index 17f36fb4ff8..78cdd31f0b0 100755 --- a/tools/gce/linux_performance_worker_init.sh +++ b/tools/gce/linux_performance_worker_init.sh @@ -55,7 +55,10 @@ sudo apt-get install -y \ libc6 \ libc6-dbg \ libc6-dev \ + libcurl4-openssl-dev \ libgtest-dev \ + libreadline-dev \ + libssl-dev \ libtool \ make \ strace \ @@ -71,7 +74,8 @@ sudo apt-get install -y \ telnet \ unzip \ wget \ - zip + zip \ + zlib1g-dev # perftools sudo apt-get install -y google-perftools libgoogle-perftools-dev @@ -87,14 +91,15 @@ sudo pip install tabulate sudo pip install google-api-python-client sudo pip install virtualenv -# TODO(jtattermusch): For some reason, building gRPC Python depends on python3.4 -# being installed, but python3.4 is not available on Ubuntu 16.04. -# Temporarily fixing this by adding a PPA with python3.4, but we should -# really remove this hack once possible. -sudo add-apt-repository -y ppa:fkrull/deadsnakes -sudo apt-get update -sudo apt-get install -y python3.4 python3.4-dev -python3.4 -m pip install virtualenv +# Building gRPC Python depends on python3.4 being installed, but python3.4 +# is not available on Ubuntu 16.10, so install from source +curl -O https://www.python.org/ftp/python/3.4.6/Python-3.4.6.tgz +tar xzvf Python-3.4.6.tgz +cd Python-3.4.6 +./configure --enable-shared --prefix=/usr/local LDFLAGS="-Wl,--rpath=/usr/local/lib" +sudo make altinstall +cd .. +rm Python-3.4.6.tgz curl -O https://bootstrap.pypa.io/get-pip.py sudo pypy get-pip.py @@ -117,18 +122,25 @@ sudo apt-get update sudo apt-get install -y mono-devel nuget # C# .NET Core dependencies (https://www.microsoft.com/net/core#ubuntu) -sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list' +sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ yakkety main" > /etc/apt/sources.list.d/dotnetdev.list' sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893 sudo apt-get update -sudo apt-get install -y dotnet-dev-1.0.0-preview2-003131 +sudo apt-get install -y dotnet-dev-1.0.0-preview2.1-003155 sudo apt-get install -y dotnet-dev-1.0.1 # Ruby dependencies -gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 -curl -sSL https://get.rvm.io | bash -s stable --ruby +git clone https://github.com/rbenv/rbenv.git ~/.rbenv +export PATH="$HOME/.rbenv/bin:$PATH" +eval "$(rbenv init -)" + +git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build +export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH" + +rbenv install 2.4.0 +rbenv global 2.4.0 +ruby -v # Install bundler (prerequisite for gRPC Ruby) -source ~/.rvm/scripts/rvm gem install bundler # Java dependencies - nothing as we already have Java JDK 8 @@ -163,15 +175,7 @@ echo 4096 | sudo tee /proc/sys/kernel/perf_event_mlock_kb git clone -v https://github.com/brendangregg/FlameGraph ~/FlameGraph # Install scipy and numpy for benchmarking scripts -sudo apt-get install python-scipy python-numpy - -# Update Linux kernel to 4.9 -wget \ - kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-headers-4.9.20-040920_4.9.20-040920.201703310531_all.deb \ - kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-headers-4.9.20-040920-generic_4.9.20-040920.201703310531_amd64.deb \ - kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.20/linux-image-4.9.20-040920-generic_4.9.20-040920.201703310531_amd64.deb -sudo dpkg -i linux-headers-4.9*.deb linux-image-4.9*.deb -rm linux-* +sudo apt-get install -y python-scipy python-numpy # Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@ # This needs to happen as the last step to prevent Jenkins master from connecting From 38279ea2e0d6c1704365a1507b9e8d487e5d7837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Vu=C4=8Dica?= Date: Wed, 18 Jan 2017 00:04:16 +0000 Subject: [PATCH 21/21] Bazel rule for building grpc_cli. --- test/cpp/util/BUILD | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index c83f89eb906..9dde22b4d1b 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -34,8 +34,8 @@ licenses(["notice"]) # 3-clause BSD cc_binary( name = "testso.so", srcs = [], - deps = ["//:grpc++_unsecure"], linkshared = 1, + deps = ["//:grpc++_unsecure"], ) cc_library( @@ -104,5 +104,29 @@ cc_test( ], ) - - +cc_binary( + name = "grpc_cli", + srcs = [ + "cli_call.cc", + "cli_call.h", + "cli_credentials.cc", + "cli_credentials.h", + "config_grpc_cli.h", + "grpc_cli.cc", + "grpc_tool.cc", + "grpc_tool.h", + "proto_file_parser.cc", + "proto_file_parser.h", + "proto_reflection_descriptor_database.cc", + "proto_reflection_descriptor_database.h", + "service_describer.cc", + "service_describer.h", + "test_config.h", + "test_config_cc.cc", + ], + deps = [ + "//:grpc++", + "//external:gflags", + "//src/proto/grpc/reflection/v1alpha:reflection_proto", + ], +)