Change handshaker API to use a read buffer to pass leftover bytes read

between handshakers.
pull/7640/head
Mark D. Roth 8 years ago
parent f14effb6e4
commit 7d9f276ea2
  1. 11
      src/core/ext/transport/chttp2/client/insecure/channel_create.c
  2. 2
      src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
  3. 13
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
  4. 6
      src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
  5. 2
      src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
  6. 12
      src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
  7. 7
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  8. 4
      src/core/ext/transport/chttp2/transport/chttp2_transport.h
  9. 25
      src/core/lib/channel/handshaker.c
  10. 8
      src/core/lib/channel/handshaker.h
  11. 8
      src/core/lib/http/httpcli_security_connector.c
  12. 9
      src/core/lib/security/transport/handshake.c
  13. 7
      src/core/lib/security/transport/handshake.h
  14. 37
      src/core/lib/security/transport/security_connector.c
  15. 14
      src/core/lib/security/transport/security_connector.h

@ -88,14 +88,21 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
} }
static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
grpc_channel_args *args, void *user_data, grpc_channel_args *args,
gpr_slice_buffer *read_buffer, void *user_data,
grpc_error *error) { grpc_error *error) {
connector *c = user_data; connector *c = user_data;
if (error != GRPC_ERROR_NONE) {
grpc_channel_args_destroy(args);
gpr_free(read_buffer);
} else {
c->result->transport = c->result->transport =
grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1); grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1);
GPR_ASSERT(c->result->transport); GPR_ASSERT(c->result->transport);
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0); grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport,
read_buffer);
c->result->channel_args = args; c->result->channel_args = args;
}
grpc_closure *notify = c->notify; grpc_closure *notify = c->notify;
c->notify = NULL; c->notify = NULL;
grpc_exec_ctx_sched(exec_ctx, notify, error, NULL); grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);

@ -75,7 +75,7 @@ grpc_channel *grpc_insecure_channel_create_from_fd(
grpc_channel *channel = grpc_channel_create( grpc_channel *channel = grpc_channel_create(
&exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); &exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
grpc_channel_args_destroy(final_args); grpc_channel_args_destroy(final_args);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL);
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);

@ -114,8 +114,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
gpr_mu_unlock(&c->mu); gpr_mu_unlock(&c->mu);
c->result->transport = grpc_create_chttp2_transport( c->result->transport = grpc_create_chttp2_transport(
exec_ctx, c->args.channel_args, secure_endpoint, 1); exec_ctx, c->args.channel_args, secure_endpoint, 1);
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL);
0);
auth_context_arg = grpc_auth_context_to_arg(auth_context); auth_context_arg = grpc_auth_context_to_arg(auth_context);
c->result->channel_args = c->result->channel_args =
grpc_channel_args_copy_and_add(c->tmp_args, &auth_context_arg, 1); grpc_channel_args_copy_and_add(c->tmp_args, &auth_context_arg, 1);
@ -126,10 +125,13 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
} }
static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
grpc_channel_args *args, void *user_data, grpc_channel_args *args,
gpr_slice_buffer *read_buffer, void *user_data,
grpc_error *error) { grpc_error *error) {
connector *c = user_data; connector *c = user_data;
c->tmp_args = args;
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
gpr_free(read_buffer);
grpc_closure *notify = c->notify; grpc_closure *notify = c->notify;
c->notify = NULL; c->notify = NULL;
grpc_exec_ctx_sched(exec_ctx, notify, error, NULL); grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
@ -137,10 +139,9 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
// TODO(roth, jboeuf): Convert security connector handshaking to use new // TODO(roth, jboeuf): Convert security connector handshaking to use new
// handshake API, and then move the code from on_secure_handshake_done() // handshake API, and then move the code from on_secure_handshake_done()
// into this function. // into this function.
c->tmp_args = args;
grpc_channel_security_connector_do_handshake( grpc_channel_security_connector_do_handshake(
exec_ctx, c->security_connector, endpoint, c->args.deadline, exec_ctx, c->security_connector, endpoint, read_buffer,
on_secure_handshake_done, c); c->args.deadline, on_secure_handshake_done, c);
} }
} }

@ -55,7 +55,8 @@ typedef struct server_connect_state {
} server_connect_state; } server_connect_state;
static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
grpc_channel_args *args, void *user_data, grpc_channel_args *args,
gpr_slice_buffer *read_buffer, void *user_data,
grpc_error *error) { grpc_error *error) {
server_connect_state *state = user_data; server_connect_state *state = user_data;
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
@ -64,6 +65,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
grpc_error_free_string(error_str); grpc_error_free_string(error_str);
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr); grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr);
gpr_free(read_buffer);
} else { } else {
// Beware that the call to grpc_create_chttp2_transport() has to happen // Beware that the call to grpc_create_chttp2_transport() has to happen
// before grpc_tcp_server_destroy(). This is fine here, but similar code // before grpc_tcp_server_destroy(). This is fine here, but similar code
@ -75,7 +77,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
grpc_server_setup_transport(exec_ctx, state->server, transport, grpc_server_setup_transport(exec_ctx, state->server, transport,
state->accepting_pollset, state->accepting_pollset,
grpc_server_get_channel_args(state->server)); grpc_server_get_channel_args(state->server));
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); grpc_chttp2_transport_start_reading(exec_ctx, transport, read_buffer);
} }
// Clean up. // Clean up.
grpc_channel_args_destroy(args); grpc_channel_args_destroy(args);

@ -67,7 +67,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
&exec_ctx, server_args, server_endpoint, 0 /* is_client */); &exec_ctx, server_args, server_endpoint, 0 /* is_client */);
grpc_endpoint_add_to_pollset(&exec_ctx, server_endpoint, grpc_cq_pollset(cq)); grpc_endpoint_add_to_pollset(&exec_ctx, server_endpoint, grpc_cq_pollset(cq));
grpc_server_setup_transport(&exec_ctx, server, transport, NULL, server_args); grpc_server_setup_transport(&exec_ctx, server, transport, NULL, server_args);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL);
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
} }

@ -111,7 +111,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
grpc_server_setup_transport(exec_ctx, state->state->server, transport, grpc_server_setup_transport(exec_ctx, state->state->server, transport,
state->accepting_pollset, args_copy); state->accepting_pollset, args_copy);
grpc_channel_args_destroy(args_copy); grpc_channel_args_destroy(args_copy);
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL);
} else { } else {
/* We need to consume this here, because the server may already have /* We need to consume this here, because the server may already have
* gone away. */ * gone away. */
@ -128,7 +128,8 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
} }
static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
grpc_channel_args *args, void *user_data, grpc_channel_args *args,
gpr_slice_buffer *read_buffer, void *user_data,
grpc_error *error) { grpc_error *error) {
server_secure_connect *state = user_data; server_secure_connect *state = user_data;
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
@ -136,9 +137,10 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str); gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
grpc_error_free_string(error_str); grpc_error_free_string(error_str);
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
grpc_channel_args_destroy(args);
gpr_free(read_buffer);
grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr); grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr);
grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr);
grpc_channel_args_destroy(args);
state_unref(state->state); state_unref(state->state);
gpr_free(state); gpr_free(state);
return; return;
@ -150,8 +152,8 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
// into this function. // into this function.
state->args = args; state->args = args;
grpc_server_security_connector_do_handshake( grpc_server_security_connector_do_handshake(
exec_ctx, state->state->sc, state->acceptor, endpoint, state->deadline, exec_ctx, state->state->sc, state->acceptor, endpoint, read_buffer,
on_secure_handshake_done, state); state->deadline, on_secure_handshake_done, state);
} }
static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp,

@ -2538,9 +2538,12 @@ grpc_transport *grpc_create_chttp2_transport(
void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx,
grpc_transport *transport, grpc_transport *transport,
gpr_slice *slices, size_t nslices) { gpr_slice_buffer *read_buffer) {
grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport; grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport;
REF_TRANSPORT(t, "reading_action"); /* matches unref inside reading_action */ REF_TRANSPORT(t, "reading_action"); /* matches unref inside reading_action */
gpr_slice_buffer_addn(&t->read_buffer, slices, nslices); if (read_buffer != NULL) {
gpr_slice_buffer_move_into(read_buffer, &t->read_buffer);
gpr_free(read_buffer);
}
reading_action(exec_ctx, t, GRPC_ERROR_NONE); reading_action(exec_ctx, t, GRPC_ERROR_NONE);
} }

@ -44,8 +44,10 @@ grpc_transport *grpc_create_chttp2_transport(
grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args, grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args,
grpc_endpoint *ep, int is_client); grpc_endpoint *ep, int is_client);
/// Takes ownership of \a read_buffer, which (if non-NULL) contains
/// leftover bytes previously read from the endpoint (e.g., by handshakers).
void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx,
grpc_transport *transport, grpc_transport *transport,
gpr_slice *slices, size_t nslices); gpr_slice_buffer *read_buffer);
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CHTTP2_TRANSPORT_H */ #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CHTTP2_TRANSPORT_H */

@ -62,11 +62,13 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
grpc_handshaker* handshaker, grpc_handshaker* handshaker,
grpc_endpoint* endpoint, grpc_endpoint* endpoint,
grpc_channel_args* args, grpc_channel_args* args,
gpr_slice_buffer* read_buffer,
gpr_timespec deadline, gpr_timespec deadline,
grpc_tcp_server_acceptor* acceptor, grpc_tcp_server_acceptor* acceptor,
grpc_handshaker_done_cb cb, void* user_data) { grpc_handshaker_done_cb cb, void* user_data) {
handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args, handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args,
deadline, acceptor, cb, user_data); read_buffer, deadline, acceptor, cb,
user_data);
} }
// //
@ -143,16 +145,17 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx,
// handshakers together. // handshakers together.
static void call_next_handshaker(grpc_exec_ctx* exec_ctx, static void call_next_handshaker(grpc_exec_ctx* exec_ctx,
grpc_endpoint* endpoint, grpc_endpoint* endpoint,
grpc_channel_args* args, void* user_data, grpc_channel_args* args,
grpc_error* error) { gpr_slice_buffer* read_buffer,
void* user_data, grpc_error* error) {
grpc_handshake_manager* mgr = user_data; grpc_handshake_manager* mgr = user_data;
GPR_ASSERT(mgr->state != NULL); GPR_ASSERT(mgr->state != NULL);
GPR_ASSERT(mgr->state->index < mgr->count); GPR_ASSERT(mgr->state->index < mgr->count);
// If we got an error, skip all remaining handshakers and invoke the // If we got an error, skip all remaining handshakers and invoke the
// caller-supplied callback immediately. // caller-supplied callback immediately.
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
mgr->state->final_cb(exec_ctx, endpoint, args, mgr->state->final_user_data, mgr->state->final_cb(exec_ctx, endpoint, args, read_buffer,
error); mgr->state->final_user_data, error);
return; return;
} }
grpc_handshaker_done_cb cb = call_next_handshaker; grpc_handshaker_done_cb cb = call_next_handshaker;
@ -164,8 +167,9 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx,
} }
// Invoke handshaker. // Invoke handshaker.
grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index], grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index],
endpoint, args, mgr->state->deadline, endpoint, args, read_buffer,
mgr->state->acceptor, cb, user_data); mgr->state->deadline, mgr->state->acceptor,
cb, user_data);
++mgr->state->index; ++mgr->state->index;
// If this is the last handshaker, clean up state. // If this is the last handshaker, clean up state.
if (mgr->state->index == mgr->count) { if (mgr->state->index == mgr->count) {
@ -180,10 +184,12 @@ void grpc_handshake_manager_do_handshake(
gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor,
grpc_handshaker_done_cb cb, void* user_data) { grpc_handshaker_done_cb cb, void* user_data) {
grpc_channel_args* args_copy = grpc_channel_args_copy(args); grpc_channel_args* args_copy = grpc_channel_args_copy(args);
gpr_slice_buffer* read_buffer = malloc(sizeof(*read_buffer));
gpr_slice_buffer_init(read_buffer);
if (mgr->count == 0) { if (mgr->count == 0) {
// No handshakers registered, so we just immediately call the done // No handshakers registered, so we just immediately call the done
// callback with the passed-in endpoint. // callback with the passed-in endpoint.
cb(exec_ctx, endpoint, args_copy, user_data, GRPC_ERROR_NONE); cb(exec_ctx, endpoint, args_copy, read_buffer, user_data, GRPC_ERROR_NONE);
} else { } else {
GPR_ASSERT(mgr->state == NULL); GPR_ASSERT(mgr->state == NULL);
mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state)); mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state));
@ -192,6 +198,7 @@ void grpc_handshake_manager_do_handshake(
mgr->state->acceptor = acceptor; mgr->state->acceptor = acceptor;
mgr->state->final_cb = cb; mgr->state->final_cb = cb;
mgr->state->final_user_data = user_data; mgr->state->final_user_data = user_data;
call_next_handshaker(exec_ctx, endpoint, args_copy, mgr, GRPC_ERROR_NONE); call_next_handshaker(exec_ctx, endpoint, args_copy, read_buffer, mgr,
GRPC_ERROR_NONE);
} }
} }

@ -36,6 +36,7 @@
#include <grpc/impl/codegen/grpc_types.h> #include <grpc/impl/codegen/grpc_types.h>
#include <grpc/impl/codegen/time.h> #include <grpc/impl/codegen/time.h>
#include <grpc/support/slice_buffer.h>
#include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/endpoint.h"
@ -56,10 +57,11 @@
typedef struct grpc_handshaker grpc_handshaker; typedef struct grpc_handshaker grpc_handshaker;
/// Callback type invoked when a handshaker is done. /// Callback type invoked when a handshaker is done.
/// Takes ownership of \a args. /// Takes ownership of \a args and \a read_buffer.
typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx, typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx,
grpc_endpoint* endpoint, grpc_endpoint* endpoint,
grpc_channel_args* args, grpc_channel_args* args,
gpr_slice_buffer* read_buffer,
void* user_data, grpc_error* error); void* user_data, grpc_error* error);
struct grpc_handshaker_vtable { struct grpc_handshaker_vtable {
@ -72,9 +74,12 @@ struct grpc_handshaker_vtable {
/// Performs handshaking. When finished, calls \a cb with \a user_data. /// Performs handshaking. When finished, calls \a cb with \a user_data.
/// Takes ownership of \a args. /// Takes ownership of \a args.
/// Takes ownership of \a read_buffer, which contains leftover bytes read
/// from the endpoint by the previous handshaker.
/// \a acceptor will be NULL for client-side handshakers. /// \a acceptor will be NULL for client-side handshakers.
void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker,
grpc_endpoint* endpoint, grpc_channel_args* args, grpc_endpoint* endpoint, grpc_channel_args* args,
gpr_slice_buffer* read_buffer,
gpr_timespec deadline, gpr_timespec deadline,
grpc_tcp_server_acceptor* acceptor, grpc_tcp_server_acceptor* acceptor,
grpc_handshaker_done_cb cb, void* user_data); grpc_handshaker_done_cb cb, void* user_data);
@ -101,6 +106,7 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
grpc_handshaker* handshaker, grpc_handshaker* handshaker,
grpc_endpoint* endpoint, grpc_endpoint* endpoint,
grpc_channel_args* args, grpc_channel_args* args,
gpr_slice_buffer* read_buffer,
gpr_timespec deadline, gpr_timespec deadline,
grpc_tcp_server_acceptor* acceptor, grpc_tcp_server_acceptor* acceptor,
grpc_handshaker_done_cb cb, void* user_data); grpc_handshaker_done_cb cb, void* user_data);

@ -61,6 +61,7 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) {
static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc, grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
gpr_slice_buffer *read_buffer,
gpr_timespec deadline, gpr_timespec deadline,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
@ -69,6 +70,7 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
tsi_result result = TSI_OK; tsi_result result = TSI_OK;
tsi_handshaker *handshaker; tsi_handshaker *handshaker;
if (c->handshaker_factory == NULL) { if (c->handshaker_factory == NULL) {
gpr_free(read_buffer);
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
return; return;
} }
@ -77,10 +79,12 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
if (result != TSI_OK) { if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result)); tsi_result_to_string(result));
gpr_free(read_buffer);
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
} else { } else {
grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
nonsecure_endpoint, deadline, cb, user_data); nonsecure_endpoint, read_buffer, deadline, cb,
user_data);
} }
} }
@ -183,7 +187,7 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
pem_root_certs, pem_root_certs_size, host, &sc) == pem_root_certs, pem_root_certs_size, host, &sc) ==
GRPC_SECURITY_OK); GRPC_SECURITY_OK);
grpc_channel_security_connector_do_handshake( grpc_channel_security_connector_do_handshake(
exec_ctx, sc, tcp, deadline, on_secure_transport_setup_done, c); exec_ctx, sc, tcp, NULL, deadline, on_secure_transport_setup_done, c);
GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
} }

@ -325,8 +325,9 @@ static void on_timeout(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
void grpc_do_security_handshake( void grpc_do_security_handshake(
grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker, grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
grpc_security_connector *connector, bool is_client_side, grpc_security_connector *connector, bool is_client_side,
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer,
grpc_security_handshake_done_cb cb, void *user_data) { gpr_timespec deadline, grpc_security_handshake_done_cb cb,
void *user_data) {
grpc_security_connector_handshake_list *handshake_node; grpc_security_connector_handshake_list *handshake_node;
grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake)); grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake));
memset(h, 0, sizeof(grpc_security_handshake)); memset(h, 0, sizeof(grpc_security_handshake));
@ -346,6 +347,10 @@ void grpc_do_security_handshake(
gpr_slice_buffer_init(&h->left_overs); gpr_slice_buffer_init(&h->left_overs);
gpr_slice_buffer_init(&h->outgoing); gpr_slice_buffer_init(&h->outgoing);
gpr_slice_buffer_init(&h->incoming); gpr_slice_buffer_init(&h->incoming);
if (read_buffer != NULL) {
gpr_slice_buffer_move_into(read_buffer, &h->incoming);
gpr_free(read_buffer);
}
if (!is_client_side) { if (!is_client_side) {
grpc_server_security_connector *server_connector = grpc_server_security_connector *server_connector =
(grpc_server_security_connector *)connector; (grpc_server_security_connector *)connector;

@ -37,12 +37,13 @@
#include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/security/transport/security_connector.h" #include "src/core/lib/security/transport/security_connector.h"
/* Calls the callback upon completion. Takes owership of handshaker. */ /* Calls the callback upon completion. Takes owership of handshaker and
* read_buffer. */
void grpc_do_security_handshake( void grpc_do_security_handshake(
grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker, grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
grpc_security_connector *connector, bool is_client_side, grpc_security_connector *connector, bool is_client_side,
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer,
grpc_security_handshake_done_cb cb, void *user_data); gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data);
void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake); void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake);

@ -127,25 +127,29 @@ void grpc_server_security_connector_shutdown(
void grpc_channel_security_connector_do_handshake( void grpc_channel_security_connector_do_handshake(
grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer,
grpc_security_handshake_done_cb cb, void *user_data) { gpr_timespec deadline, grpc_security_handshake_done_cb cb,
void *user_data) {
if (sc == NULL || nonsecure_endpoint == NULL) { if (sc == NULL || nonsecure_endpoint == NULL) {
gpr_free(read_buffer);
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
} else { } else {
sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, deadline, cb, user_data); sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, read_buffer, deadline,
cb, user_data);
} }
} }
void grpc_server_security_connector_do_handshake( void grpc_server_security_connector_do_handshake(
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
gpr_timespec deadline, grpc_security_handshake_done_cb cb, gpr_slice_buffer *read_buffer, gpr_timespec deadline,
void *user_data) { grpc_security_handshake_done_cb cb, void *user_data) {
if (sc == NULL || nonsecure_endpoint == NULL) { if (sc == NULL || nonsecure_endpoint == NULL) {
gpr_free(read_buffer);
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
} else { } else {
sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, deadline, cb, sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, read_buffer,
user_data); deadline, cb, user_data);
} }
} }
@ -312,23 +316,26 @@ static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx,
static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx, static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc, grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
gpr_slice_buffer *read_buffer,
gpr_timespec deadline, gpr_timespec deadline,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base, grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base,
true, nonsecure_endpoint, deadline, cb, user_data); true, nonsecure_endpoint, read_buffer, deadline,
cb, user_data);
} }
static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx, static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_server_security_connector *sc, grpc_server_security_connector *sc,
grpc_tcp_server_acceptor *acceptor, grpc_tcp_server_acceptor *acceptor,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
gpr_slice_buffer *read_buffer,
gpr_timespec deadline, gpr_timespec deadline,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base, grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base,
false, nonsecure_endpoint, deadline, cb, false, nonsecure_endpoint, read_buffer, deadline,
user_data); cb, user_data);
} }
static grpc_security_connector_vtable fake_channel_vtable = { static grpc_security_connector_vtable fake_channel_vtable = {
@ -418,6 +425,7 @@ static grpc_security_status ssl_create_handshaker(
static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc, grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
gpr_slice_buffer *read_buffer,
gpr_timespec deadline, gpr_timespec deadline,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
@ -430,10 +438,12 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
: c->target_name, : c->target_name,
&handshaker); &handshaker);
if (status != GRPC_SECURITY_OK) { if (status != GRPC_SECURITY_OK) {
gpr_free(read_buffer);
cb(exec_ctx, user_data, status, NULL, NULL); cb(exec_ctx, user_data, status, NULL, NULL);
} else { } else {
grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
nonsecure_endpoint, deadline, cb, user_data); nonsecure_endpoint, read_buffer, deadline, cb,
user_data);
} }
} }
@ -441,6 +451,7 @@ static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_server_security_connector *sc, grpc_server_security_connector *sc,
grpc_tcp_server_acceptor *acceptor, grpc_tcp_server_acceptor *acceptor,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
gpr_slice_buffer *read_buffer,
gpr_timespec deadline, gpr_timespec deadline,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
@ -450,10 +461,12 @@ static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_status status = grpc_security_status status =
ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker); ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker);
if (status != GRPC_SECURITY_OK) { if (status != GRPC_SECURITY_OK) {
gpr_free(read_buffer);
cb(exec_ctx, user_data, status, NULL, NULL); cb(exec_ctx, user_data, status, NULL, NULL);
} else { } else {
grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false, grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false,
nonsecure_endpoint, deadline, cb, user_data); nonsecure_endpoint, read_buffer, deadline, cb,
user_data);
} }
} }

@ -143,7 +143,8 @@ struct grpc_channel_security_connector {
grpc_security_call_host_check_cb cb, void *user_data); grpc_security_call_host_check_cb cb, void *user_data);
void (*do_handshake)(grpc_exec_ctx *exec_ctx, void (*do_handshake)(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc, grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, grpc_endpoint *nonsecure_endpoint,
gpr_slice_buffer *read_buffer, gpr_timespec deadline,
grpc_security_handshake_done_cb cb, void *user_data); grpc_security_handshake_done_cb cb, void *user_data);
}; };
@ -156,8 +157,9 @@ void grpc_channel_security_connector_check_call_host(
/* Handshake. */ /* Handshake. */
void grpc_channel_security_connector_do_handshake( void grpc_channel_security_connector_do_handshake(
grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector, grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector,
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer,
grpc_security_handshake_done_cb cb, void *user_data); gpr_timespec deadline, grpc_security_handshake_done_cb cb,
void *user_data);
/* --- server_security_connector object. --- /* --- server_security_connector object. ---
@ -174,14 +176,16 @@ struct grpc_server_security_connector {
void (*do_handshake)(grpc_exec_ctx *exec_ctx, void (*do_handshake)(grpc_exec_ctx *exec_ctx,
grpc_server_security_connector *sc, grpc_server_security_connector *sc,
grpc_tcp_server_acceptor *acceptor, grpc_tcp_server_acceptor *acceptor,
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, grpc_endpoint *nonsecure_endpoint,
gpr_slice_buffer *read_buffer, gpr_timespec deadline,
grpc_security_handshake_done_cb cb, void *user_data); grpc_security_handshake_done_cb cb, void *user_data);
}; };
void grpc_server_security_connector_do_handshake( void grpc_server_security_connector_do_handshake(
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); gpr_slice_buffer *read_buffer, gpr_timespec deadline,
grpc_security_handshake_done_cb cb, void *user_data);
void grpc_server_security_connector_shutdown( void grpc_server_security_connector_shutdown(
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector); grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector);

Loading…
Cancel
Save