From 20b9f9432836b8959c034a01c51325d9c3b7c00a Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Fri, 7 Apr 2017 12:50:33 -0700 Subject: Update TSI with new non-blocking TSI interfaces. --- 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 ++++++++++++++++++++++------ 7 files changed, 580 insertions(+), 52 deletions(-) create mode 100644 src/core/tsi/transport_security_adapter.c create mode 100644 src/core/tsi/transport_security_adapter.h (limited to 'src') diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c index 822fad51cb..1836beefc4 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 a0325cc183..c4dba002f8 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 67ebe1b1f3..a9cb6a107c 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 491fa1a8bd..2e82110827 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 0000000000..7e0b8f574a --- /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 0000000000..de5aaefd5f --- /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 caed43eac4..be04810e24 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 -- cgit v1.2.3 From 7400d1ce7548328d0107cea3ebe4dd0488bfe642 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 7 Apr 2017 10:17:40 -0700 Subject: Ignore a couple of errors in the Node express benchmark --- src/node/performance/benchmark_client_express.js | 25 ++++++++++++++++-------- src/node/performance/benchmark_server_express.js | 4 ++-- 2 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/node/performance/benchmark_client_express.js b/src/node/performance/benchmark_client_express.js index 675eb5f288..e749956599 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 065bcf660b..4b695eb467 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; -- cgit v1.2.3 From 9cb19b8e2429389dc68045aa7f61384f4b03660f Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 7 Apr 2017 14:17:41 -0700 Subject: 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(-) (limited to 'src') diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h index be6857c482..dd63c21ff1 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 a509d311d4..5cce3c1672 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 efb6f4d493..b82e80d8e3 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 d3a83b188f..df71777e4b 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 11729c425c..b473dd1f52 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) { -- cgit v1.2.3 From e69881de7fd5a2f09ad92986c48e5fa2a013bb34 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Mon, 10 Apr 2017 14:29:43 -0700 Subject: 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 + tools/run_tests/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. (limited to 'src') diff --git a/BUILD b/BUILD index 1991c86743..70ce0ecb6b 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 f8b88645cb..3b11066625 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 3444fa53db..b64ff58f5c 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 6fbc8d9166..e5bec63ed0 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 2846781031..1be815e3f3 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 83c19afc24..78d2f15778 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 6a204685a0..abbd6f4251 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 6957ecca73..7a301aa830 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 a9cb6a107c..aa8808ab74 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 2e82110827..a4c9cbc001 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 0000000000..e69de29bb2 diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c index 7e0b8f574a..60cebdd6f2 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 be04810e24..c9495f80b6 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 3bcbe667e2..88e783815c 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 6903a0e5d5..55a707d919 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 11176d9756..c871256d6e 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 948af2f29e..1fec7fb353 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 d43b0e3f83..28776121ec 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 -- cgit v1.2.3 From a2a2024944a92ec1dbf0ec827659ee408cb4c1e3 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Mon, 10 Apr 2017 15:03:21 -0700 Subject: Use handshaker_result_created in tsi_adapter_handshaker --- src/core/tsi/transport_security_adapter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c index 60cebdd6f2..ebf0279139 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; } -- cgit v1.2.3 From c19550272e4883c30ab50e301617b3e04e8db39a Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Tue, 11 Apr 2017 09:36:19 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c index aa8808ab74..b11c00c43c 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 ebf0279139..d83339b3eb 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 de5aaefd5f..686618b53b 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 c9495f80b6..f2112b62b6 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, -- cgit v1.2.3 From c953b62d396d6168507520d837550f6b12d7e729 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Tue, 11 Apr 2017 10:16:19 -0700 Subject: 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. (limited to 'src') diff --git a/src/core/tsi/transport_security_adapter. b/src/core/tsi/transport_security_adapter. deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/core/tsi/transport_security_adapter.c b/src/core/tsi/transport_security_adapter.c index d83339b3eb..9f2147b530 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; -- cgit v1.2.3 From e0e961aae70a3764d211de8f07610585db63daf2 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Mon, 24 Apr 2017 09:11:44 -0700 Subject: 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 (limited to 'src') diff --git a/memory_usage.csv b/memory_usage.csv new file mode 100644 index 0000000000..6eaf90f61f --- /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 686618b53b..e4dc07515f 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 -- cgit v1.2.3 From f2263e14ca778e0a42d896ad5228c671fbb97aed Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Mon, 24 Apr 2017 15:32:03 -0700 Subject: 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 (limited to 'src') diff --git a/memory_usage.csv b/memory_usage.csv deleted file mode 100644 index 6eaf90f61f..0000000000 --- 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 e4dc07515f..400df2f11b 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 */ -- cgit v1.2.3