Transfer the ownership of the handshaker.

pull/3027/head
Julien Boeuf 9 years ago
parent 694ef25a07
commit db5282b2dc
  1. 9
      src/core/httpcli/httpcli_security_connector.c
  2. 27
      src/core/security/handshake.c
  3. 5
      src/core/security/handshake.h
  4. 28
      src/core/security/security_connector.c
  5. 1
      src/core/security/security_connector.h

@ -55,7 +55,6 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name);
tsi_handshaker_destroy(sc->handshaker);
gpr_free(sc);
}
@ -65,20 +64,20 @@ static void httpcli_ssl_do_handshake(
grpc_httpcli_ssl_channel_security_connector *c =
(grpc_httpcli_ssl_channel_security_connector *)sc;
tsi_result result = TSI_OK;
tsi_handshaker *handshaker;
if (c->handshaker_factory == NULL) {
cb(user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL);
return;
}
tsi_handshaker_destroy(sc->handshaker);
sc->handshaker = NULL;
result = tsi_ssl_handshaker_factory_create_handshaker(
c->handshaker_factory, c->secure_peer_name, &sc->handshaker);
c->handshaker_factory, c->secure_peer_name, &handshaker);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result));
cb(user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL);
} else {
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
grpc_do_security_handshake(handshaker, sc, nonsecure_endpoint, cb,
user_data);
}
}

@ -44,6 +44,7 @@
typedef struct {
grpc_security_connector *connector;
tsi_handshaker *handshaker;
unsigned char *handshake_buffer;
size_t handshake_buffer_size;
grpc_endpoint *wrapped_endpoint;
@ -77,6 +78,8 @@ static void security_handshake_done(grpc_security_handshake *h,
}
if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer);
gpr_slice_buffer_destroy(&h->left_overs);
tsi_handshaker_destroy(h->handshaker);
GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake");
gpr_free(h);
}
@ -89,8 +92,8 @@ static void on_peer_checked(void *user_data, grpc_security_status status) {
security_handshake_done(h, 0);
return;
}
result = tsi_handshaker_create_frame_protector(h->connector->handshaker, NULL,
&protector);
result =
tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Frame protector creation failed with error %s.",
tsi_result_to_string(result));
@ -107,8 +110,7 @@ static void on_peer_checked(void *user_data, grpc_security_status status) {
static void check_peer(grpc_security_handshake *h) {
grpc_security_status peer_status;
tsi_peer peer;
tsi_result result =
tsi_handshaker_extract_peer(h->connector->handshaker, &peer);
tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Peer extraction failed with error %s",
@ -136,7 +138,7 @@ static void send_handshake_bytes_to_peer(grpc_security_handshake *h) {
do {
size_t to_send_size = h->handshake_buffer_size - offset;
result = tsi_handshaker_get_bytes_to_send_to_peer(
h->connector->handshaker, h->handshake_buffer + offset, &to_send_size);
h->handshaker, h->handshake_buffer + offset, &to_send_size);
offset += to_send_size;
if (result == TSI_INCOMPLETE_DATA) {
h->handshake_buffer_size *= 2;
@ -193,12 +195,11 @@ static void on_handshake_data_received_from_peer(
for (i = 0; i < nslices; i++) {
consumed_slice_size = GPR_SLICE_LENGTH(slices[i]);
result = tsi_handshaker_process_bytes_from_peer(
h->connector->handshaker, GPR_SLICE_START_PTR(slices[i]),
&consumed_slice_size);
if (!tsi_handshaker_is_in_progress(h->connector->handshaker)) break;
h->handshaker, GPR_SLICE_START_PTR(slices[i]), &consumed_slice_size);
if (!tsi_handshaker_is_in_progress(h->handshaker)) break;
}
if (tsi_handshaker_is_in_progress(h->connector->handshaker)) {
if (tsi_handshaker_is_in_progress(h->handshaker)) {
/* We may need more data. */
if (result == TSI_INCOMPLETE_DATA) {
/* TODO(klempner,jboeuf): This should probably use the client setup
@ -258,7 +259,7 @@ static void on_handshake_data_sent_to_peer(void *handshake,
}
/* We may be done. */
if (tsi_handshaker_is_in_progress(h->connector->handshaker)) {
if (tsi_handshaker_is_in_progress(h->handshaker)) {
/* TODO(klempner,jboeuf): This should probably use the client setup
deadline */
grpc_endpoint_notify_on_read(
@ -268,13 +269,15 @@ static void on_handshake_data_sent_to_peer(void *handshake,
}
}
void grpc_do_security_handshake(grpc_security_connector *connector,
void grpc_do_security_handshake(tsi_handshaker *handshaker,
grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake));
memset(h, 0, sizeof(grpc_security_handshake));
h->connector = connector;
h->handshaker = handshaker;
h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake");
h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
h->handshake_buffer = gpr_malloc(h->handshake_buffer_size);
h->wrapped_endpoint = nonsecure_endpoint;

@ -38,8 +38,9 @@
#include "src/core/security/security_connector.h"
/* Calls the callback upon completion. */
void grpc_do_security_handshake(grpc_security_connector *connector,
/* Calls the callback upon completion. Takes owership of handshaker. */
void grpc_do_security_handshake(tsi_handshaker *handshaker,
grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data);

@ -222,13 +222,11 @@ typedef struct {
static void fake_channel_destroy(grpc_security_connector *sc) {
grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
grpc_credentials_unref(c->request_metadata_creds);
tsi_handshaker_destroy(sc->handshaker);
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
static void fake_server_destroy(grpc_security_connector *sc) {
tsi_handshaker_destroy(sc->handshaker);
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
@ -286,18 +284,16 @@ static void fake_channel_do_handshake(grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
tsi_handshaker_destroy(sc->handshaker);
sc->handshaker = tsi_create_fake_handshaker(1);
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
grpc_do_security_handshake(tsi_create_fake_handshaker(1), sc,
nonsecure_endpoint, cb, user_data);
}
static void fake_server_do_handshake(grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
tsi_handshaker_destroy(sc->handshaker);
sc->handshaker = tsi_create_fake_handshaker(0);
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
grpc_do_security_handshake(tsi_create_fake_handshaker(0), sc,
nonsecure_endpoint, cb, user_data);
}
static grpc_security_connector_vtable fake_channel_vtable = {
@ -358,7 +354,6 @@ static void ssl_channel_destroy(grpc_security_connector *sc) {
if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
tsi_peer_destruct(&c->peer);
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
tsi_handshaker_destroy(sc->handshaker);
gpr_free(sc);
}
@ -369,7 +364,6 @@ static void ssl_server_destroy(grpc_security_connector *sc) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
tsi_handshaker_destroy(sc->handshaker);
gpr_free(sc);
}
@ -378,8 +372,6 @@ static grpc_security_status ssl_create_handshaker(
const char *peer_name, tsi_handshaker **handshaker) {
tsi_result result = TSI_OK;
if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
tsi_handshaker_destroy(*handshaker);
*handshaker = NULL;
result = tsi_ssl_handshaker_factory_create_handshaker(
handshaker_factory, is_client ? peer_name : NULL, handshaker);
if (result != TSI_OK) {
@ -396,15 +388,17 @@ static void ssl_channel_do_handshake(grpc_security_connector *sc,
void *user_data) {
grpc_ssl_channel_security_connector *c =
(grpc_ssl_channel_security_connector *)sc;
tsi_handshaker *handshaker;
grpc_security_status status = ssl_create_handshaker(
c->handshaker_factory, 1,
c->overridden_target_name != NULL ? c->overridden_target_name
: c->target_name,
&sc->handshaker);
&handshaker);
if (status != GRPC_SECURITY_OK) {
cb(user_data, status, nonsecure_endpoint, NULL);
} else {
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
grpc_do_security_handshake(handshaker, sc, nonsecure_endpoint, cb,
user_data);
}
}
@ -414,12 +408,14 @@ static void ssl_server_do_handshake(grpc_security_connector *sc,
void *user_data) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
tsi_handshaker *handshaker;
grpc_security_status status =
ssl_create_handshaker(c->handshaker_factory, 0, NULL, &sc->handshaker);
ssl_create_handshaker(c->handshaker_factory, 0, NULL, &handshaker);
if (status != GRPC_SECURITY_OK) {
cb(user_data, status, nonsecure_endpoint, NULL);
} else {
grpc_do_security_handshake(sc, nonsecure_endpoint, cb, user_data);
grpc_do_security_handshake(handshaker, sc, nonsecure_endpoint, cb,
user_data);
}
}

@ -84,7 +84,6 @@ struct grpc_security_connector {
gpr_refcount refcount;
int is_client_side;
const char *url_scheme;
tsi_handshaker *handshaker;
grpc_auth_context *auth_context; /* Populated after the peer is checked. */
};

Loading…
Cancel
Save