pull/10925/head
jiangtaoli2016 8 years ago
parent 4cae6d0951
commit 22cc52aa9b
  1. 4
      src/core/lib/http/httpcli_security_connector.c
  2. 71
      src/core/lib/security/transport/security_handshaker.c

@ -44,6 +44,7 @@
#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security_adapter.h"
typedef struct { typedef struct {
grpc_channel_security_connector base; grpc_channel_security_connector base;
@ -78,7 +79,8 @@ static void httpcli_ssl_add_handshakers(grpc_exec_ctx *exec_ctx,
} }
grpc_handshake_manager_add( grpc_handshake_manager_add(
handshake_mgr, handshake_mgr,
grpc_security_handshaker_create(exec_ctx, handshaker, &sc->base)); grpc_security_handshaker_create(
exec_ctx, tsi_create_adapter_handshaker(handshaker), &sc->base));
} }
static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx, static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx,

@ -154,19 +154,19 @@ static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
} }
// Create frame protector. // Create frame protector.
tsi_frame_protector *protector; tsi_frame_protector *protector;
tsi_result status = tsi_handshaker_result_create_frame_protector( tsi_result result = tsi_handshaker_result_create_frame_protector(
h->handshaker_result, NULL, &protector); h->handshaker_result, NULL, &protector);
if (status != TSI_OK) { if (result != TSI_OK) {
error = grpc_set_tsi_error_result( error = grpc_set_tsi_error_result(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Frame protector creation failed"), GRPC_ERROR_CREATE_FROM_STATIC_STRING("Frame protector creation failed"),
status); result);
security_handshake_failed_locked(exec_ctx, h, error); security_handshake_failed_locked(exec_ctx, h, error);
goto done; goto done;
} }
// Get unused bytes. // Get unused bytes.
unsigned char *unused_bytes = NULL; unsigned char *unused_bytes = NULL;
size_t unused_bytes_size = 0; size_t unused_bytes_size = 0;
status = tsi_handshaker_result_get_unused_bytes( result = tsi_handshaker_result_get_unused_bytes(
h->handshaker_result, &unused_bytes, &unused_bytes_size); h->handshaker_result, &unused_bytes, &unused_bytes_size);
if (unused_bytes_size > 0) { if (unused_bytes_size > 0) {
gpr_slice slice = gpr_slice slice =
@ -202,11 +202,11 @@ done:
static grpc_error *check_peer_locked(grpc_exec_ctx *exec_ctx, static grpc_error *check_peer_locked(grpc_exec_ctx *exec_ctx,
security_handshaker *h) { security_handshaker *h) {
tsi_peer peer; tsi_peer peer;
tsi_result status = tsi_result result =
tsi_handshaker_result_extract_peer(h->handshaker_result, &peer); tsi_handshaker_result_extract_peer(h->handshaker_result, &peer);
if (status != TSI_OK) { if (result != TSI_OK) {
return grpc_set_tsi_error_result( return grpc_set_tsi_error_result(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), status); GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result);
} }
grpc_security_connector_check_peer(exec_ctx, h->connector, peer, grpc_security_connector_check_peer(exec_ctx, h->connector, peer,
&h->auth_context, &h->on_peer_checked); &h->auth_context, &h->on_peer_checked);
@ -214,51 +214,49 @@ static grpc_error *check_peer_locked(grpc_exec_ctx *exec_ctx,
} }
static grpc_error *on_handshake_next_done_locked( static grpc_error *on_handshake_next_done_locked(
grpc_exec_ctx *exec_ctx, security_handshaker *h, tsi_result status, grpc_exec_ctx *exec_ctx, security_handshaker *h, tsi_result result,
const unsigned char *bytes_to_send, size_t bytes_to_send_size, const unsigned char *bytes_to_send, size_t bytes_to_send_size,
tsi_handshaker_result *result) { tsi_handshaker_result *handshaker_result) {
grpc_error *error = GRPC_ERROR_NONE; grpc_error *error = GRPC_ERROR_NONE;
// Read more if we need to. // Read more if we need to.
if (status == TSI_INCOMPLETE_DATA) { if (result == TSI_INCOMPLETE_DATA) {
GPR_ASSERT(bytes_to_send_size == 0); GPR_ASSERT(bytes_to_send_size == 0);
grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer, grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer,
&h->on_handshake_data_received_from_peer); &h->on_handshake_data_received_from_peer);
return error; return error;
} }
if (result != TSI_OK) {
if (status != TSI_OK) {
return grpc_set_tsi_error_result( return grpc_set_tsi_error_result(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), status); GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result);
} }
// If there are data to send to the peer, send data. // Send data to peer.
if (bytes_to_send_size > 0) { grpc_slice to_send = grpc_slice_from_copied_buffer(
grpc_slice to_send = grpc_slice_from_copied_buffer( (const char *)bytes_to_send, bytes_to_send_size);
(const char *)bytes_to_send, bytes_to_send_size); grpc_slice_buffer_reset_and_unref(&h->outgoing);
grpc_slice_buffer_reset_and_unref(&h->outgoing); grpc_slice_buffer_add(&h->outgoing, to_send);
grpc_slice_buffer_add(&h->outgoing, to_send); grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing,
grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing, &h->on_handshake_data_sent_to_peer);
&h->on_handshake_data_sent_to_peer);
}
// If handshake has completed, check peer and so on. // If handshake has completed, check peer and so on.
if (result != NULL) { if (handshaker_result != NULL) {
h->handshaker_result = result; h->handshaker_result = handshaker_result;
error = check_peer_locked(exec_ctx, h); error = check_peer_locked(exec_ctx, h);
} }
return error; return error;
} }
static void on_handshake_next_done_grpc_wrapper( static void on_handshake_next_done_grpc_wrapper(
tsi_result status, void *user_data, const unsigned char *bytes_to_send, tsi_result result, void *user_data, const unsigned char *bytes_to_send,
size_t bytes_to_send_size, tsi_handshaker_result *result) { size_t bytes_to_send_size, tsi_handshaker_result *handshaker_result) {
security_handshaker *h = user_data; security_handshaker *h = user_data;
// This callback will be invoked by TSI in a non-grpc thread, so it's // This callback will be invoked by TSI in a non-grpc thread, so it's
// safe to create our own exec_ctx here. // safe to create our own exec_ctx here.
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_mu_lock(&h->mu); gpr_mu_lock(&h->mu);
grpc_error *error = on_handshake_next_done_locked( grpc_error *error =
&exec_ctx, h, status, bytes_to_send, bytes_to_send_size, result); on_handshake_next_done_locked(&exec_ctx, h, result, bytes_to_send,
bytes_to_send_size, handshaker_result);
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
security_handshake_failed_locked(&exec_ctx, h, error); security_handshake_failed_locked(&exec_ctx, h, error);
gpr_mu_unlock(&h->mu); gpr_mu_unlock(&h->mu);
@ -275,19 +273,20 @@ static grpc_error *do_handshaker_next_locked(
// Invoke TSI handshaker. // Invoke TSI handshaker.
unsigned char *bytes_to_send = NULL; unsigned char *bytes_to_send = NULL;
size_t bytes_to_send_size = 0; size_t bytes_to_send_size = 0;
tsi_handshaker_result *result = NULL; tsi_handshaker_result *handshaker_result = NULL;
tsi_result status = tsi_handshaker_next( tsi_result result = tsi_handshaker_next(
h->handshaker, bytes_received, bytes_received_size, &bytes_to_send, h->handshaker, bytes_received, bytes_received_size, &bytes_to_send,
&bytes_to_send_size, &result, &on_handshake_next_done_grpc_wrapper, h); &bytes_to_send_size, &handshaker_result,
if (status == TSI_ASYNC) { &on_handshake_next_done_grpc_wrapper, h);
if (result == TSI_ASYNC) {
// Handshaker operating asynchronously. Nothing else to do here; // Handshaker operating asynchronously. Nothing else to do here;
// callback will be invoked in a TSI thread. // callback will be invoked in a TSI thread.
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }
// Handshaker returned synchronously. Invoke callback directly in // Handshaker returned synchronously. Invoke callback directly in
// this thread with our existing exec_ctx. // this thread with our existing exec_ctx.
return on_handshake_next_done_locked(exec_ctx, h, status, bytes_to_send, return on_handshake_next_done_locked(exec_ctx, h, result, bytes_to_send,
bytes_to_send_size, result); bytes_to_send_size, handshaker_result);
} }
static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx, static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
@ -344,9 +343,7 @@ static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *arg,
security_handshaker_unref(exec_ctx, h); security_handshaker_unref(exec_ctx, h);
return; return;
} }
if (h->handshaker_result != NULL) { if (h->handshaker_result == NULL) {
check_peer_locked(exec_ctx, h);
} else {
grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer, grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer,
&h->on_handshake_data_received_from_peer); &h->on_handshake_data_received_from_peer);
} }

Loading…
Cancel
Save