diff options
32 files changed, 423 insertions, 292 deletions
@@ -134,10 +134,10 @@ cc_library( "src/core/security/auth_filters.h", "src/core/security/base64.h", "src/core/security/credentials.h", + "src/core/security/handshake.h", "src/core/security/json_token.h", "src/core/security/jwt_verifier.h", "src/core/security/secure_endpoint.h", - "src/core/security/secure_transport_setup.h", "src/core/security/security_connector.h", "src/core/security/security_context.h", "src/core/tsi/fake_transport_security.h", @@ -259,10 +259,10 @@ cc_library( "src/core/security/credentials_posix.c", "src/core/security/credentials_win32.c", "src/core/security/google_default_credentials.c", + "src/core/security/handshake.c", "src/core/security/json_token.c", "src/core/security/jwt_verifier.c", "src/core/security/secure_endpoint.c", - "src/core/security/secure_transport_setup.c", "src/core/security/security_connector.c", "src/core/security/security_context.c", "src/core/security/server_auth_filter.c", @@ -1034,10 +1034,10 @@ objc_library( "src/core/security/credentials_posix.c", "src/core/security/credentials_win32.c", "src/core/security/google_default_credentials.c", + "src/core/security/handshake.c", "src/core/security/json_token.c", "src/core/security/jwt_verifier.c", "src/core/security/secure_endpoint.c", - "src/core/security/secure_transport_setup.c", "src/core/security/security_connector.c", "src/core/security/security_context.c", "src/core/security/server_auth_filter.c", @@ -1182,10 +1182,10 @@ objc_library( "src/core/security/auth_filters.h", "src/core/security/base64.h", "src/core/security/credentials.h", + "src/core/security/handshake.h", "src/core/security/json_token.h", "src/core/security/jwt_verifier.h", "src/core/security/secure_endpoint.h", - "src/core/security/secure_transport_setup.h", "src/core/security/security_connector.h", "src/core/security/security_context.h", "src/core/tsi/fake_transport_security.h", @@ -4027,10 +4027,10 @@ LIBGRPC_SRC = \ src/core/security/credentials_posix.c \ src/core/security/credentials_win32.c \ src/core/security/google_default_credentials.c \ + src/core/security/handshake.c \ src/core/security/json_token.c \ src/core/security/jwt_verifier.c \ src/core/security/secure_endpoint.c \ - src/core/security/secure_transport_setup.c \ src/core/security/security_connector.c \ src/core/security/security_context.c \ src/core/security/server_auth_filter.c \ @@ -20552,10 +20552,10 @@ src/core/security/credentials_metadata.c: $(OPENSSL_DEP) src/core/security/credentials_posix.c: $(OPENSSL_DEP) src/core/security/credentials_win32.c: $(OPENSSL_DEP) src/core/security/google_default_credentials.c: $(OPENSSL_DEP) +src/core/security/handshake.c: $(OPENSSL_DEP) src/core/security/json_token.c: $(OPENSSL_DEP) src/core/security/jwt_verifier.c: $(OPENSSL_DEP) src/core/security/secure_endpoint.c: $(OPENSSL_DEP) -src/core/security/secure_transport_setup.c: $(OPENSSL_DEP) src/core/security/security_connector.c: $(OPENSSL_DEP) src/core/security/security_context.c: $(OPENSSL_DEP) src/core/security/server_auth_filter.c: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 298552048e..527b7d5944 100644 --- a/build.yaml +++ b/build.yaml @@ -179,15 +179,15 @@ libs: language: c public_headers: [include/grpc/grpc_security.h] headers: [src/core/security/auth_filters.h, src/core/security/base64.h, src/core/security/credentials.h, - src/core/security/json_token.h, src/core/security/jwt_verifier.h, src/core/security/secure_endpoint.h, - src/core/security/secure_transport_setup.h, src/core/security/security_connector.h, - src/core/security/security_context.h, src/core/tsi/fake_transport_security.h, - src/core/tsi/ssl_transport_security.h, src/core/tsi/transport_security.h, src/core/tsi/transport_security_interface.h] + src/core/security/handshake.h, src/core/security/json_token.h, src/core/security/jwt_verifier.h, + src/core/security/secure_endpoint.h, src/core/security/security_connector.h, src/core/security/security_context.h, + src/core/tsi/fake_transport_security.h, src/core/tsi/ssl_transport_security.h, + src/core/tsi/transport_security.h, src/core/tsi/transport_security_interface.h] src: [src/core/httpcli/httpcli_security_connector.c, src/core/security/base64.c, src/core/security/client_auth_filter.c, src/core/security/credentials.c, src/core/security/credentials_metadata.c, src/core/security/credentials_posix.c, src/core/security/credentials_win32.c, - src/core/security/google_default_credentials.c, src/core/security/json_token.c, - src/core/security/jwt_verifier.c, src/core/security/secure_endpoint.c, src/core/security/secure_transport_setup.c, + src/core/security/google_default_credentials.c, src/core/security/handshake.c, + src/core/security/json_token.c, src/core/security/jwt_verifier.c, src/core/security/secure_endpoint.c, src/core/security/security_connector.c, src/core/security/security_context.c, src/core/security/server_auth_filter.c, src/core/security/server_secure_chttp2.c, src/core/surface/init_secure.c, src/core/surface/secure_channel_create.c, src/core/tsi/fake_transport_security.c, diff --git a/gRPC.podspec b/gRPC.podspec index 3b069f290d..5a16504787 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -136,10 +136,10 @@ Pod::Spec.new do |s| 'src/core/security/auth_filters.h', 'src/core/security/base64.h', 'src/core/security/credentials.h', + 'src/core/security/handshake.h', 'src/core/security/json_token.h', 'src/core/security/jwt_verifier.h', 'src/core/security/secure_endpoint.h', - 'src/core/security/secure_transport_setup.h', 'src/core/security/security_connector.h', 'src/core/security/security_context.h', 'src/core/tsi/fake_transport_security.h', @@ -268,10 +268,10 @@ Pod::Spec.new do |s| 'src/core/security/credentials_posix.c', 'src/core/security/credentials_win32.c', 'src/core/security/google_default_credentials.c', + 'src/core/security/handshake.c', 'src/core/security/json_token.c', 'src/core/security/jwt_verifier.c', 'src/core/security/secure_endpoint.c', - 'src/core/security/secure_transport_setup.c', 'src/core/security/security_connector.c', 'src/core/security/security_context.c', 'src/core/security/server_auth_filter.c', @@ -416,10 +416,10 @@ Pod::Spec.new do |s| 'src/core/security/auth_filters.h', 'src/core/security/base64.h', 'src/core/security/credentials.h', + 'src/core/security/handshake.h', 'src/core/security/json_token.h', 'src/core/security/jwt_verifier.h', 'src/core/security/secure_endpoint.h', - 'src/core/security/secure_transport_setup.h', 'src/core/security/security_connector.h', 'src/core/security/security_context.h', 'src/core/tsi/fake_transport_security.h', diff --git a/include/grpc++/security/credentials.h b/include/grpc++/security/credentials.h index 01b9710f6b..fafcfdc906 100644 --- a/include/grpc++/security/credentials.h +++ b/include/grpc++/security/credentials.h @@ -177,7 +177,7 @@ class MetadataCredentialsPlugin { // a different thread from the one processing the call. virtual bool IsBlocking() const { return true; } - // Gets the auth metatada produced by this plugin. */ + // Gets the auth metatada produced by this plugin. virtual Status GetMetadata( grpc::string_ref service_url, std::multimap<grpc::string, grpc::string_ref>* metadata) = 0; diff --git a/src/core/channel/channel_args.h b/src/core/channel/channel_args.h index 06a6012dee..1a6be91359 100644 --- a/src/core/channel/channel_args.h +++ b/src/core/channel/channel_args.h @@ -71,7 +71,7 @@ grpc_channel_args *grpc_channel_args_set_compression_algorithm( * compression algorithms are enabled. It's an error to disable an algorithm set * by grpc_channel_args_set_compression_algorithm. * - * Returns an instance will the updated algorithm states. The \a a pointer is + * Returns an instance with the updated algorithm states. The \a a pointer is * modified to point to the returned instance (which may be different from the * input value of \a a). */ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state( diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index ec832a0367..5f20f8c16d 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -70,7 +70,7 @@ typedef struct channel_data { /* used to silence 'variable not used' warnings */ static void ignore_unused(void *ignored) {} -static grpc_mdelem *client_filter(void *user_data, grpc_mdelem *md) { +static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) { grpc_call_element *elem = user_data; channel_data *channeld = elem->channel_data; if (md == channeld->status) { @@ -78,6 +78,8 @@ static grpc_mdelem *client_filter(void *user_data, grpc_mdelem *md) { } else if (md->key == channeld->status->key) { grpc_call_element_send_cancel(elem); return NULL; + } else if (md->key == channeld->content_type->key) { + return NULL; } return md; } @@ -92,11 +94,13 @@ static void hc_on_recv(void *user_data, int success) { grpc_stream_op *op = &ops[i]; if (op->type != GRPC_OP_METADATA) continue; calld->got_initial_metadata = 1; - grpc_metadata_batch_filter(&op->data.metadata, client_filter, elem); + grpc_metadata_batch_filter(&op->data.metadata, client_recv_filter, elem); } calld->on_done_recv->cb(calld->on_done_recv->cb_arg, success); } + + static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { grpc_call_element *elem = user_data; channel_data *channeld = elem->channel_data; diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c index 2f061946a1..9898efd608 100644 --- a/src/core/channel/http_server_filter.c +++ b/src/core/channel/http_server_filter.c @@ -111,8 +111,7 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { return NULL; } else if (md->key == channeld->te_trailers->key || md->key == channeld->method_post->key || - md->key == channeld->http_scheme->key || - md->key == channeld->content_type->key) { + md->key == channeld->http_scheme->key) { gpr_log(GPR_ERROR, "Invalid %s: header: '%s'", grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)); /* swallow it and error everything out. */ diff --git a/src/core/httpcli/httpcli_security_connector.c b/src/core/httpcli/httpcli_security_connector.c index 7887f9d530..86f34db1d0 100644 --- a/src/core/httpcli/httpcli_security_connector.c +++ b/src/core/httpcli/httpcli_security_connector.c @@ -35,7 +35,7 @@ #include <string.h> -#include "src/core/security/secure_transport_setup.h" +#include "src/core/security/handshake.h" #include "src/core/support/string.h" #include <grpc/support/alloc.h> #include <grpc/support/log.h> @@ -58,20 +58,27 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) { gpr_free(sc); } -static grpc_security_status httpcli_ssl_create_handshaker( - grpc_security_connector *sc, tsi_handshaker **handshaker) { +static void httpcli_ssl_do_handshake( + grpc_security_connector *sc, grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, void *user_data) { grpc_httpcli_ssl_channel_security_connector *c = (grpc_httpcli_ssl_channel_security_connector *)sc; tsi_result result = TSI_OK; - if (c->handshaker_factory == NULL) return GRPC_SECURITY_ERROR; + tsi_handshaker *handshaker; + if (c->handshaker_factory == NULL) { + cb(user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL); + return; + } result = tsi_ssl_handshaker_factory_create_handshaker( - c->handshaker_factory, c->secure_peer_name, 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)); - return GRPC_SECURITY_ERROR; + cb(user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL); + } else { + grpc_do_security_handshake(handshaker, sc, nonsecure_endpoint, cb, + user_data); } - return GRPC_SECURITY_OK; } static grpc_security_status httpcli_ssl_check_peer(grpc_security_connector *sc, @@ -94,7 +101,7 @@ static grpc_security_status httpcli_ssl_check_peer(grpc_security_connector *sc, } static grpc_security_connector_vtable httpcli_ssl_vtable = { - httpcli_ssl_destroy, httpcli_ssl_create_handshaker, httpcli_ssl_check_peer}; + httpcli_ssl_destroy, httpcli_ssl_do_handshake, httpcli_ssl_check_peer}; static grpc_security_status httpcli_ssl_channel_security_connector_create( const unsigned char *pem_root_certs, size_t pem_root_certs_size, @@ -169,8 +176,8 @@ static void ssl_handshake(void *arg, grpc_endpoint *tcp, const char *host, GPR_ASSERT(httpcli_ssl_channel_security_connector_create( pem_root_certs, pem_root_certs_size, host, &sc) == GRPC_SECURITY_OK); - grpc_setup_secure_transport(&sc->base, tcp, on_secure_transport_setup_done, - c); + grpc_security_connector_do_handshake(&sc->base, tcp, + on_secure_transport_setup_done, c); GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); } diff --git a/src/core/iomgr/tcp_client_windows.c b/src/core/iomgr/tcp_client_windows.c index a42ec7cf11..6f57de0289 100644 --- a/src/core/iomgr/tcp_client_windows.c +++ b/src/core/iomgr/tcp_client_windows.c @@ -121,7 +121,7 @@ static void on_connect(void *acp, int from_iocp) { notification request for the connection, and one timeout alert. */ void grpc_tcp_client_connect(void (*cb)(void *arg, grpc_endpoint *tcp), void *arg, grpc_pollset_set *interested_parties, - const struct sockaddr *addr, int addr_len, + const struct sockaddr *addr, size_t addr_len, gpr_timespec deadline) { SOCKET sock = INVALID_SOCKET; BOOL success; @@ -176,7 +176,7 @@ void grpc_tcp_client_connect(void (*cb)(void *arg, grpc_endpoint *tcp), socket = grpc_winsocket_create(sock, "client"); info = &socket->write_info; - success = ConnectEx(sock, addr, addr_len, NULL, 0, NULL, &info->overlapped); + success = ConnectEx(sock, addr, (int)addr_len, NULL, 0, NULL, &info->overlapped); /* It wouldn't be unusual to get a success immediately. But we'll still get an IOCP notification, so let's ignore it. */ diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c index a043baafae..c42e5e7527 100644 --- a/src/core/iomgr/tcp_server_windows.c +++ b/src/core/iomgr/tcp_server_windows.c @@ -96,7 +96,6 @@ grpc_tcp_server *grpc_tcp_server_create(void) { grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server)); gpr_mu_init(&s->mu); s->active_ports = 0; - s->iomgr_callbacks_pending = 0; s->on_accept_cb = NULL; s->on_accept_cb_arg = NULL; s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP); @@ -156,7 +155,7 @@ void grpc_tcp_server_destroy(grpc_tcp_server *s, /* Prepare (bind) a recently-created socket for listening. */ static int prepare_socket(SOCKET sock, const struct sockaddr *addr, - int addr_len) { + size_t addr_len) { struct sockaddr_storage sockname_temp; socklen_t sockname_len; @@ -169,7 +168,7 @@ static int prepare_socket(SOCKET sock, const struct sockaddr *addr, goto error; } - if (bind(sock, addr, addr_len) == SOCKET_ERROR) { + if (bind(sock, addr, (int)addr_len) == SOCKET_ERROR) { char *addr_str; char *utf8_message = gpr_format_message(WSAGetLastError()); grpc_sockaddr_to_string(&addr_str, addr, 0); @@ -355,7 +354,7 @@ static void on_accept(void *arg, int from_iocp) { } static int add_socket_to_server(grpc_tcp_server *s, SOCKET sock, - const struct sockaddr *addr, int addr_len) { + const struct sockaddr *addr, size_t addr_len) { server_port *sp; int port; int status; @@ -402,7 +401,7 @@ static int add_socket_to_server(grpc_tcp_server *s, SOCKET sock, } int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, - int addr_len) { + size_t addr_len) { int allocated_port = -1; unsigned i; SOCKET sock; diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/handshake.c index bf0079577e..3b49271373 100644 --- a/src/core/security/secure_transport_setup.c +++ b/src/core/security/handshake.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/secure_transport_setup.h" +#include "src/core/security/handshake.h" #include <string.h> @@ -52,133 +52,134 @@ typedef struct { gpr_slice_buffer left_overs; gpr_slice_buffer incoming; gpr_slice_buffer outgoing; - grpc_secure_transport_setup_done_cb cb; + grpc_security_handshake_done_cb cb; void *user_data; grpc_iomgr_closure on_handshake_data_sent_to_peer; grpc_iomgr_closure on_handshake_data_received_from_peer; -} grpc_secure_transport_setup; +} grpc_security_handshake; + static void on_handshake_data_received_from_peer(void *setup, int success); static void on_handshake_data_sent_to_peer(void *setup, int success); -static void secure_transport_setup_done(grpc_secure_transport_setup *s, - int is_success) { +static void security_handshake_done(grpc_security_handshake *h, + int is_success) { if (is_success) { - s->cb(s->user_data, GRPC_SECURITY_OK, s->wrapped_endpoint, - s->secure_endpoint); + h->cb(h->user_data, GRPC_SECURITY_OK, h->wrapped_endpoint, + h->secure_endpoint); } else { - if (s->secure_endpoint != NULL) { - grpc_endpoint_shutdown(s->secure_endpoint); - grpc_endpoint_destroy(s->secure_endpoint); + if (h->secure_endpoint != NULL) { + grpc_endpoint_shutdown(h->secure_endpoint); + grpc_endpoint_destroy(h->secure_endpoint); } else { - grpc_endpoint_destroy(s->wrapped_endpoint); + grpc_endpoint_destroy(h->wrapped_endpoint); } - s->cb(s->user_data, GRPC_SECURITY_ERROR, s->wrapped_endpoint, NULL); + h->cb(h->user_data, GRPC_SECURITY_ERROR, h->wrapped_endpoint, NULL); } - if (s->handshaker != NULL) tsi_handshaker_destroy(s->handshaker); - if (s->handshake_buffer != NULL) gpr_free(s->handshake_buffer); - gpr_slice_buffer_destroy(&s->left_overs); - gpr_slice_buffer_destroy(&s->outgoing); - gpr_slice_buffer_destroy(&s->incoming); - GRPC_SECURITY_CONNECTOR_UNREF(s->connector, "secure_transport_setup"); - gpr_free(s); + if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker); + if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer); + gpr_slice_buffer_destroy(&h->left_overs); + gpr_slice_buffer_destroy(&h->outgoing); + gpr_slice_buffer_destroy(&h->incoming); + GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake"); + gpr_free(h); } static void on_peer_checked(void *user_data, grpc_security_status status) { - grpc_secure_transport_setup *s = user_data; + grpc_security_handshake *h = user_data; tsi_frame_protector *protector; tsi_result result; if (status != GRPC_SECURITY_OK) { gpr_log(GPR_ERROR, "Error checking peer."); - secure_transport_setup_done(s, 0); + security_handshake_done(h, 0); return; } result = - tsi_handshaker_create_frame_protector(s->handshaker, NULL, &protector); + 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)); - secure_transport_setup_done(s, 0); + security_handshake_done(h, 0); return; } - s->secure_endpoint = - grpc_secure_endpoint_create(protector, s->wrapped_endpoint, - s->left_overs.slices, s->left_overs.count); - s->left_overs.count = 0; - s->left_overs.length = 0; - secure_transport_setup_done(s, 1); + h->secure_endpoint = + grpc_secure_endpoint_create(protector, h->wrapped_endpoint, + h->left_overs.slices, h->left_overs.count); + h->left_overs.count = 0; + h->left_overs.length = 0; + security_handshake_done(h, 1); return; } -static void check_peer(grpc_secure_transport_setup *s) { +static void check_peer(grpc_security_handshake *h) { grpc_security_status peer_status; tsi_peer peer; - tsi_result result = tsi_handshaker_extract_peer(s->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", tsi_result_to_string(result)); - secure_transport_setup_done(s, 0); + security_handshake_done(h, 0); return; } - peer_status = grpc_security_connector_check_peer(s->connector, peer, - on_peer_checked, s); + peer_status = grpc_security_connector_check_peer(h->connector, peer, + on_peer_checked, h); if (peer_status == GRPC_SECURITY_ERROR) { gpr_log(GPR_ERROR, "Peer check failed."); - secure_transport_setup_done(s, 0); + security_handshake_done(h, 0); return; } else if (peer_status == GRPC_SECURITY_OK) { - on_peer_checked(s, peer_status); + on_peer_checked(h, peer_status); } } -static void send_handshake_bytes_to_peer(grpc_secure_transport_setup *s) { +static void send_handshake_bytes_to_peer(grpc_security_handshake *h) { size_t offset = 0; tsi_result result = TSI_OK; gpr_slice to_send; do { - size_t to_send_size = s->handshake_buffer_size - offset; + size_t to_send_size = h->handshake_buffer_size - offset; result = tsi_handshaker_get_bytes_to_send_to_peer( - s->handshaker, s->handshake_buffer + offset, &to_send_size); + h->handshaker, h->handshake_buffer + offset, &to_send_size); offset += to_send_size; if (result == TSI_INCOMPLETE_DATA) { - s->handshake_buffer_size *= 2; - s->handshake_buffer = - gpr_realloc(s->handshake_buffer, s->handshake_buffer_size); + h->handshake_buffer_size *= 2; + h->handshake_buffer = + gpr_realloc(h->handshake_buffer, h->handshake_buffer_size); } } while (result == TSI_INCOMPLETE_DATA); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshake failed with error %s", tsi_result_to_string(result)); - secure_transport_setup_done(s, 0); + security_handshake_done(h, 0); return; } to_send = - gpr_slice_from_copied_buffer((const char *)s->handshake_buffer, offset); - gpr_slice_buffer_reset_and_unref(&s->outgoing); - gpr_slice_buffer_add(&s->outgoing, to_send); + gpr_slice_from_copied_buffer((const char *)h->handshake_buffer, offset); + gpr_slice_buffer_reset_and_unref(&h->outgoing); + gpr_slice_buffer_add(&h->outgoing, to_send); /* TODO(klempner,jboeuf): This should probably use the client setup deadline */ - switch (grpc_endpoint_write(s->wrapped_endpoint, &s->outgoing, - &s->on_handshake_data_sent_to_peer)) { + switch (grpc_endpoint_write(h->wrapped_endpoint, &h->outgoing, + &h->on_handshake_data_sent_to_peer)) { case GRPC_ENDPOINT_ERROR: gpr_log(GPR_ERROR, "Could not send handshake data to peer."); - secure_transport_setup_done(s, 0); + security_handshake_done(h, 0); break; case GRPC_ENDPOINT_DONE: - on_handshake_data_sent_to_peer(s, 1); + on_handshake_data_sent_to_peer(h, 1); break; case GRPC_ENDPOINT_PENDING: break; } } -static void on_handshake_data_received_from_peer(void *setup, int success) { - grpc_secure_transport_setup *s = setup; +static void on_handshake_data_received_from_peer(void *handshake, int success) { + grpc_security_handshake *h = handshake; size_t consumed_slice_size = 0; tsi_result result = TSI_OK; size_t i; @@ -187,35 +188,35 @@ static void on_handshake_data_received_from_peer(void *setup, int success) { if (!success) { gpr_log(GPR_ERROR, "Read failed."); - secure_transport_setup_done(s, 0); + security_handshake_done(h, 0); return; } - for (i = 0; i < s->incoming.count; i++) { - consumed_slice_size = GPR_SLICE_LENGTH(s->incoming.slices[i]); + for (i = 0; i < h->incoming.count; i++) { + consumed_slice_size = GPR_SLICE_LENGTH(h->incoming.slices[i]); result = tsi_handshaker_process_bytes_from_peer( - s->handshaker, GPR_SLICE_START_PTR(s->incoming.slices[i]), + h->handshaker, GPR_SLICE_START_PTR(h->incoming.slices[i]), &consumed_slice_size); - if (!tsi_handshaker_is_in_progress(s->handshaker)) break; + if (!tsi_handshaker_is_in_progress(h->handshaker)) break; } - if (tsi_handshaker_is_in_progress(s->handshaker)) { + if (tsi_handshaker_is_in_progress(h->handshaker)) { /* We may need more data. */ if (result == TSI_INCOMPLETE_DATA) { - switch (grpc_endpoint_read(s->wrapped_endpoint, &s->incoming, - &s->on_handshake_data_received_from_peer)) { + switch (grpc_endpoint_read(h->wrapped_endpoint, &h->incoming, + &h->on_handshake_data_received_from_peer)) { case GRPC_ENDPOINT_DONE: - on_handshake_data_received_from_peer(s, 1); + on_handshake_data_received_from_peer(h, 1); break; case GRPC_ENDPOINT_ERROR: - on_handshake_data_received_from_peer(s, 0); + on_handshake_data_received_from_peer(h, 0); break; case GRPC_ENDPOINT_PENDING: break; } return; } else { - send_handshake_bytes_to_peer(s); + send_handshake_bytes_to_peer(h); return; } } @@ -223,90 +224,85 @@ static void on_handshake_data_received_from_peer(void *setup, int success) { if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshake failed with error %s", tsi_result_to_string(result)); - secure_transport_setup_done(s, 0); + security_handshake_done(h, 0); return; } /* Handshake is done and successful this point. */ has_left_overs_in_current_slice = - (consumed_slice_size < GPR_SLICE_LENGTH(s->incoming.slices[i])); + (consumed_slice_size < GPR_SLICE_LENGTH(h->incoming.slices[i])); num_left_overs = - (has_left_overs_in_current_slice ? 1 : 0) + s->incoming.count - i - 1; + (has_left_overs_in_current_slice ? 1 : 0) + h->incoming.count - i - 1; if (num_left_overs == 0) { - check_peer(s); + check_peer(h); return; } + /* Put the leftovers in our buffer (ownership transfered). */ if (has_left_overs_in_current_slice) { gpr_slice_buffer_add( - &s->left_overs, - gpr_slice_split_tail(&s->incoming.slices[i], consumed_slice_size)); + &h->left_overs, + gpr_slice_split_tail(&h->incoming.slices[i], consumed_slice_size)); gpr_slice_unref( - s->incoming.slices[i]); /* split_tail above increments refcount. */ + h->incoming.slices[i]); /* split_tail above increments refcount. */ } gpr_slice_buffer_addn( - &s->left_overs, &s->incoming.slices[i + 1], + &h->left_overs, &h->incoming.slices[i + 1], num_left_overs - (size_t)has_left_overs_in_current_slice); - check_peer(s); + check_peer(h); } -/* If setup is NULL, the setup is done. */ -static void on_handshake_data_sent_to_peer(void *setup, int success) { - grpc_secure_transport_setup *s = setup; +/* If handshake is NULL, the handshake is done. */ +static void on_handshake_data_sent_to_peer(void *handshake, int success) { + grpc_security_handshake *h = handshake; /* Make sure that write is OK. */ if (!success) { gpr_log(GPR_ERROR, "Write failed."); - if (setup != NULL) secure_transport_setup_done(s, 0); + if (handshake != NULL) security_handshake_done(h, 0); return; } /* We may be done. */ - if (tsi_handshaker_is_in_progress(s->handshaker)) { + if (tsi_handshaker_is_in_progress(h->handshaker)) { /* TODO(klempner,jboeuf): This should probably use the client setup deadline */ - switch (grpc_endpoint_read(s->wrapped_endpoint, &s->incoming, - &s->on_handshake_data_received_from_peer)) { + switch (grpc_endpoint_read(h->wrapped_endpoint, &h->incoming, + &h->on_handshake_data_received_from_peer)) { case GRPC_ENDPOINT_ERROR: - on_handshake_data_received_from_peer(s, 0); + on_handshake_data_received_from_peer(h, 0); break; case GRPC_ENDPOINT_PENDING: break; case GRPC_ENDPOINT_DONE: - on_handshake_data_received_from_peer(s, 1); + on_handshake_data_received_from_peer(h, 1); break; } } else { - check_peer(s); + check_peer(h); } } -void grpc_setup_secure_transport(grpc_security_connector *connector, - grpc_endpoint *nonsecure_endpoint, - grpc_secure_transport_setup_done_cb cb, - void *user_data) { - grpc_security_status result = GRPC_SECURITY_OK; - grpc_secure_transport_setup *s = - gpr_malloc(sizeof(grpc_secure_transport_setup)); - memset(s, 0, sizeof(grpc_secure_transport_setup)); - result = grpc_security_connector_create_handshaker(connector, &s->handshaker); - if (result != GRPC_SECURITY_OK) { - secure_transport_setup_done(s, 0); - return; - } - s->connector = - GRPC_SECURITY_CONNECTOR_REF(connector, "secure_transport_setup"); - s->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; - s->handshake_buffer = gpr_malloc(s->handshake_buffer_size); - s->wrapped_endpoint = nonsecure_endpoint; - s->user_data = user_data; - s->cb = cb; - grpc_iomgr_closure_init(&s->on_handshake_data_sent_to_peer, - on_handshake_data_sent_to_peer, s); - grpc_iomgr_closure_init(&s->on_handshake_data_received_from_peer, - on_handshake_data_received_from_peer, s); - gpr_slice_buffer_init(&s->left_overs); - gpr_slice_buffer_init(&s->outgoing); - gpr_slice_buffer_init(&s->incoming); - send_handshake_bytes_to_peer(s); +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->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; + h->user_data = user_data; + h->cb = cb; + grpc_iomgr_closure_init(&h->on_handshake_data_sent_to_peer, + on_handshake_data_sent_to_peer, h); + grpc_iomgr_closure_init(&h->on_handshake_data_received_from_peer, + on_handshake_data_received_from_peer, h); + gpr_slice_buffer_init(&h->left_overs); + gpr_slice_buffer_init(&h->outgoing); + gpr_slice_buffer_init(&h->incoming); + send_handshake_bytes_to_peer(h); } diff --git a/src/core/security/secure_transport_setup.h b/src/core/security/handshake.h index d9b802556d..d7e4a30580 100644 --- a/src/core/security/secure_transport_setup.h +++ b/src/core/security/handshake.h @@ -31,23 +31,18 @@ * */ -#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H -#define GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H +#ifndef GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H +#define GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H #include "src/core/iomgr/endpoint.h" #include "src/core/security/security_connector.h" -/* --- Secure transport setup --- */ -/* Ownership of the secure_endpoint is transfered. */ -typedef void (*grpc_secure_transport_setup_done_cb)( - void *user_data, grpc_security_status status, - grpc_endpoint *wrapped_endpoint, grpc_endpoint *secure_endpoint); +/* 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); -/* Calls the callback upon completion. */ -void grpc_setup_secure_transport(grpc_security_connector *connector, - grpc_endpoint *nonsecure_endpoint, - grpc_secure_transport_setup_done_cb cb, - void *user_data); - -#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H */ +#endif /* GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H */ diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c index ba9ac68c5f..f6460a323e 100644 --- a/src/core/security/security_connector.c +++ b/src/core/security/security_connector.c @@ -36,6 +36,7 @@ #include <string.h> #include "src/core/security/credentials.h" +#include "src/core/security/handshake.h" #include "src/core/security/secure_endpoint.h" #include "src/core/security/security_context.h" #include "src/core/support/env.h" @@ -101,10 +102,15 @@ const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer, return NULL; } -grpc_security_status grpc_security_connector_create_handshaker( - grpc_security_connector *sc, tsi_handshaker **handshaker) { - if (sc == NULL || handshaker == NULL) return GRPC_SECURITY_ERROR; - return sc->vtable->create_handshaker(sc, handshaker); +void grpc_security_connector_do_handshake(grpc_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { + if (sc == NULL || nonsecure_endpoint == NULL) { + cb(user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL); + } else { + sc->vtable->do_handshake(sc, nonsecure_endpoint, cb, user_data); + } } grpc_security_status grpc_security_connector_check_peer( @@ -225,18 +231,6 @@ static void fake_server_destroy(grpc_security_connector *sc) { gpr_free(sc); } -static grpc_security_status fake_channel_create_handshaker( - grpc_security_connector *sc, tsi_handshaker **handshaker) { - *handshaker = tsi_create_fake_handshaker(1); - return GRPC_SECURITY_OK; -} - -static grpc_security_status fake_server_create_handshaker( - grpc_security_connector *sc, tsi_handshaker **handshaker) { - *handshaker = tsi_create_fake_handshaker(0); - return GRPC_SECURITY_OK; -} - static grpc_security_status fake_check_peer(grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb, @@ -286,11 +280,27 @@ static grpc_security_status fake_channel_check_call_host( } } +static void fake_channel_do_handshake(grpc_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *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) { + grpc_do_security_handshake(tsi_create_fake_handshaker(0), sc, + nonsecure_endpoint, cb, user_data); +} + static grpc_security_connector_vtable fake_channel_vtable = { - fake_channel_destroy, fake_channel_create_handshaker, fake_check_peer}; + fake_channel_destroy, fake_channel_do_handshake, fake_check_peer}; static grpc_security_connector_vtable fake_server_vtable = { - fake_server_destroy, fake_server_create_handshaker, fake_check_peer}; + fake_server_destroy, fake_server_do_handshake, fake_check_peer}; grpc_channel_security_connector *grpc_fake_channel_security_connector_create( grpc_credentials *request_metadata_creds, int call_host_check_is_async) { @@ -372,22 +382,41 @@ static grpc_security_status ssl_create_handshaker( return GRPC_SECURITY_OK; } -static grpc_security_status ssl_channel_create_handshaker( - grpc_security_connector *sc, tsi_handshaker **handshaker) { +static void ssl_channel_do_handshake(grpc_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { grpc_ssl_channel_security_connector *c = (grpc_ssl_channel_security_connector *)sc; - return ssl_create_handshaker(c->handshaker_factory, 1, - c->overridden_target_name != NULL - ? c->overridden_target_name - : c->target_name, - handshaker); + 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, + &handshaker); + if (status != GRPC_SECURITY_OK) { + cb(user_data, status, nonsecure_endpoint, NULL); + } else { + grpc_do_security_handshake(handshaker, sc, nonsecure_endpoint, cb, + user_data); + } } -static grpc_security_status ssl_server_create_handshaker( - grpc_security_connector *sc, tsi_handshaker **handshaker) { +static void ssl_server_do_handshake(grpc_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { grpc_ssl_server_security_connector *c = (grpc_ssl_server_security_connector *)sc; - return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker); + tsi_handshaker *handshaker; + grpc_security_status status = + 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(handshaker, sc, nonsecure_endpoint, cb, + user_data); + } } static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) { @@ -512,10 +541,10 @@ static grpc_security_status ssl_channel_check_call_host( } static grpc_security_connector_vtable ssl_channel_vtable = { - ssl_channel_destroy, ssl_channel_create_handshaker, ssl_channel_check_peer}; + ssl_channel_destroy, ssl_channel_do_handshake, ssl_channel_check_peer}; static grpc_security_connector_vtable ssl_server_vtable = { - ssl_server_destroy, ssl_server_create_handshaker, ssl_server_check_peer}; + ssl_server_destroy, ssl_server_do_handshake, ssl_server_check_peer}; static gpr_slice default_pem_root_certs; diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h index 2c9aa1c5a4..5fc1db382e 100644 --- a/src/core/security/security_connector.h +++ b/src/core/security/security_connector.h @@ -63,10 +63,17 @@ typedef struct grpc_security_connector grpc_security_connector; typedef void (*grpc_security_check_cb)(void *user_data, grpc_security_status status); + +/* Ownership of the secure_endpoint is transfered. */ +typedef void (*grpc_security_handshake_done_cb)( + void *user_data, grpc_security_status status, + grpc_endpoint *wrapped_endpoint, grpc_endpoint *secure_endpoint); + typedef struct { void (*destroy)(grpc_security_connector *sc); - grpc_security_status (*create_handshaker)(grpc_security_connector *sc, - tsi_handshaker **handshaker); + void (*do_handshake)(grpc_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, void *user_data); grpc_security_status (*check_peer)(grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb, void *user_data); @@ -100,9 +107,11 @@ grpc_security_connector *grpc_security_connector_ref( void grpc_security_connector_unref(grpc_security_connector *policy); #endif -/* Handshake creation. */ -grpc_security_status grpc_security_connector_create_handshaker( - grpc_security_connector *sc, tsi_handshaker **handshaker); +/* Handshake. */ +void grpc_security_connector_do_handshake(grpc_security_connector *connector, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data); /* Check the peer. Implementations can choose to check the peer either synchronously or diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index 4749f5f516..f7318b2079 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -44,7 +44,6 @@ #include "src/core/security/credentials.h" #include "src/core/security/security_connector.h" #include "src/core/security/security_context.h" -#include "src/core/security/secure_transport_setup.h" #include "src/core/surface/server.h" #include "src/core/transport/chttp2_transport.h" #include <grpc/support/alloc.h> @@ -123,10 +122,9 @@ static int remove_tcp_from_list_locked(grpc_server_secure_state *state, return -1; } -static void on_secure_transport_setup_done(void *statep, - grpc_security_status status, - grpc_endpoint *wrapped_endpoint, - grpc_endpoint *secure_endpoint) { +static void on_secure_handshake_done(void *statep, grpc_security_status status, + grpc_endpoint *wrapped_endpoint, + grpc_endpoint *secure_endpoint) { grpc_server_secure_state *state = statep; grpc_transport *transport; grpc_mdctx *mdctx; @@ -165,8 +163,8 @@ static void on_accept(void *statep, grpc_endpoint *tcp) { node->next = state->handshaking_tcp_endpoints; state->handshaking_tcp_endpoints = node; gpr_mu_unlock(&state->mu); - grpc_setup_secure_transport(state->sc, tcp, on_secure_transport_setup_done, - state); + grpc_security_connector_do_handshake(state->sc, tcp, on_secure_handshake_done, + state); } /* Server callback: start listening on our ports */ diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 1636998f59..4168c2ef0c 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -1485,8 +1485,6 @@ static void recv_metadata(grpc_call *call, grpc_metadata_batch *md) { } else if (key == grpc_channel_get_encodings_accepted_by_peer_string( call->channel)) { set_encodings_accepted_by_peer(call, md->value->slice); - } else if (key == grpc_channel_get_content_type_string(call->channel)) { - continue; /* swallow "content-type" header */ } else { dest = &call->buffered_metadata[is_trailing]; if (dest->count == dest->capacity) { diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index cc9d44f45d..a89523b3ab 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -69,7 +69,6 @@ struct grpc_channel { grpc_mdstr *grpc_compression_algorithm_string; grpc_mdstr *grpc_encodings_accepted_by_peer_string; grpc_mdstr *grpc_message_string; - grpc_mdstr *content_type_string; grpc_mdstr *path_string; grpc_mdstr *authority_string; grpc_mdelem *default_authority; @@ -112,8 +111,6 @@ grpc_channel *grpc_channel_create_from_filters( grpc_mdstr_from_string(mdctx, "grpc-accept-encoding", 0); channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message", 0); - channel->content_type_string = - grpc_mdstr_from_string(mdctx, "content-type", 0); for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) { char buf[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa((long)i, buf); @@ -284,7 +281,6 @@ static void destroy_channel(void *p, int ok) { GRPC_MDSTR_UNREF(channel->grpc_compression_algorithm_string); GRPC_MDSTR_UNREF(channel->grpc_encodings_accepted_by_peer_string); GRPC_MDSTR_UNREF(channel->grpc_message_string); - GRPC_MDSTR_UNREF(channel->content_type_string); GRPC_MDSTR_UNREF(channel->path_string); GRPC_MDSTR_UNREF(channel->authority_string); while (channel->registered_calls) { @@ -368,10 +364,6 @@ grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel) { return channel->grpc_message_string; } -grpc_mdstr *grpc_channel_get_content_type_string(grpc_channel *channel) { - return channel->content_type_string; -} - gpr_uint32 grpc_channel_get_max_message_length(grpc_channel *channel) { return channel->max_message_length; } diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h index 05fbc8d75c..f271616f60 100644 --- a/src/core/surface/channel.h +++ b/src/core/surface/channel.h @@ -59,7 +59,6 @@ grpc_mdstr *grpc_channel_get_compression_algorithm_string( grpc_mdstr *grpc_channel_get_encodings_accepted_by_peer_string( grpc_channel *channel); grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel); -grpc_mdstr *grpc_channel_get_content_type_string(grpc_channel *channel); gpr_uint32 grpc_channel_get_max_message_length(grpc_channel *channel); #ifdef GRPC_CHANNEL_REF_COUNT_DEBUG diff --git a/src/core/surface/channel_connectivity.c b/src/core/surface/channel_connectivity.c index 88a7c16598..5c55ad3655 100644 --- a/src/core/surface/channel_connectivity.c +++ b/src/core/surface/channel_connectivity.c @@ -67,6 +67,7 @@ typedef struct { gpr_mu mu; callback_phase phase; int success; + int removed; grpc_iomgr_closure on_complete; grpc_alarm alarm; grpc_connectivity_state state; @@ -77,10 +78,6 @@ typedef struct { } state_watcher; static void delete_state_watcher(state_watcher *w) { - grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(w->channel)); - grpc_client_channel_del_interested_party(client_channel_elem, - grpc_cq_pollset(w->cq)); GRPC_CHANNEL_INTERNAL_UNREF(w->channel, "watch_connectivity"); gpr_mu_destroy(&w->mu); gpr_free(w); @@ -112,7 +109,17 @@ static void finished_completion(void *pw, grpc_cq_completion *ignored) { static void partly_done(state_watcher *w, int due_to_completion) { int delete = 0; + grpc_channel_element *client_channel_elem = NULL; + gpr_mu_lock(&w->mu); + if (w->removed == 0) { + w->removed = 1; + client_channel_elem = grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(w->channel)); + grpc_client_channel_del_interested_party(client_channel_elem, + grpc_cq_pollset(w->cq)); + } + gpr_mu_unlock(&w->mu); if (due_to_completion) { gpr_mu_lock(&w->mu); w->success = 1; @@ -163,6 +170,7 @@ void grpc_channel_watch_connectivity_state( w->phase = WAITING; w->state = last_observed_state; w->success = 0; + w->removed = 0; w->cq = cq; w->tag = tag; w->channel = channel; diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index 52c5e93988..289bf0111c 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -47,7 +47,6 @@ #include "src/core/iomgr/tcp_client.h" #include "src/core/security/auth_filters.h" #include "src/core/security/credentials.h" -#include "src/core/security/secure_transport_setup.h" #include "src/core/surface/channel.h" #include "src/core/transport/chttp2_transport.h" #include "src/core/tsi/transport_security_interface.h" @@ -78,10 +77,9 @@ static void connector_unref(grpc_connector *con) { } } -static void on_secure_transport_setup_done(void *arg, - grpc_security_status status, - grpc_endpoint *wrapped_endpoint, - grpc_endpoint *secure_endpoint) { +static void on_secure_handshake_done(void *arg, grpc_security_status status, + grpc_endpoint *wrapped_endpoint, + grpc_endpoint *secure_endpoint) { connector *c = arg; grpc_iomgr_closure *notify; gpr_mu_lock(&c->mu); @@ -90,7 +88,7 @@ static void on_secure_transport_setup_done(void *arg, gpr_mu_unlock(&c->mu); } else if (status != GRPC_SECURITY_OK) { GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint); - gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status); + gpr_log(GPR_ERROR, "Secure handshake failed with error %d.", status); memset(c->result, 0, sizeof(*c->result)); c->connecting_endpoint = NULL; gpr_mu_unlock(&c->mu); @@ -119,8 +117,8 @@ static void connected(void *arg, grpc_endpoint *tcp) { GPR_ASSERT(c->connecting_endpoint == NULL); c->connecting_endpoint = tcp; gpr_mu_unlock(&c->mu); - grpc_setup_secure_transport(&c->security_connector->base, tcp, - on_secure_transport_setup_done, c); + grpc_security_connector_do_handshake(&c->security_connector->base, tcp, + on_secure_handshake_done, c); } else { memset(c->result, 0, sizeof(*c->result)); notify = c->notify; diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 8333b01f29..99b7468e86 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -183,7 +183,7 @@ void MetadataCredentialsPluginWrapper::InvokePlugin( 0, {{nullptr, nullptr, nullptr, nullptr}}}); } - cb(user_data, &md[0], md.size(), + cb(user_data, md.empty() ? nullptr : &md[0], md.size(), static_cast<grpc_status_code>(status.error_code()), status.error_message().c_str()); } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index bfe799bd15..b3cfcd51a7 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1149,6 +1149,24 @@ TEST_F(End2endTest, ChannelState) { EXPECT_EQ(GRPC_CHANNEL_CONNECTING, channel_->GetState(false)); } +// Takes 10s. +TEST_F(End2endTest, ChannelStateTimeout) { + int port = grpc_pick_unused_port_or_die(); + std::ostringstream server_address; + server_address << "127.0.0.1:" << port; + // Channel to non-existing server + auto channel = CreateChannel(server_address.str(), InsecureCredentials()); + // Start IDLE + EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true)); + + auto state = GRPC_CHANNEL_IDLE; + for (int i = 0; i < 10; i++) { + channel->WaitForStateChange(state, std::chrono::system_clock::now() + + std::chrono::seconds(1)); + state = channel->GetState(false); + } +} + // Talking to a non-existing service. TEST_F(End2endTest, NonExistingService) { ResetChannel(); diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 106d235a21..8b88d54331 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -770,10 +770,10 @@ include/grpc/census.h \ src/core/security/auth_filters.h \ src/core/security/base64.h \ src/core/security/credentials.h \ +src/core/security/handshake.h \ src/core/security/json_token.h \ src/core/security/jwt_verifier.h \ src/core/security/secure_endpoint.h \ -src/core/security/secure_transport_setup.h \ src/core/security/security_connector.h \ src/core/security/security_context.h \ src/core/tsi/fake_transport_security.h \ @@ -895,10 +895,10 @@ src/core/security/credentials_metadata.c \ src/core/security/credentials_posix.c \ src/core/security/credentials_win32.c \ src/core/security/google_default_credentials.c \ +src/core/security/handshake.c \ src/core/security/json_token.c \ src/core/security/jwt_verifier.c \ src/core/security/secure_endpoint.c \ -src/core/security/secure_transport_setup.c \ src/core/security/security_connector.c \ src/core/security/security_context.c \ src/core/security/server_auth_filter.c \ diff --git a/tools/jenkins/build_docker_and_run_tests.sh b/tools/jenkins/build_docker_and_run_tests.sh new file mode 100755 index 0000000000..fa6bd44e18 --- /dev/null +++ b/tools/jenkins/build_docker_and_run_tests.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# Copyright 2015, 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. +# +# This script is invoked by run_tests.py to accommodate "test under docker" +# scenario. You should never need to call this script on your own. + +set -ex + +cd `dirname $0`/../.. +git_root=`pwd` +cd - + +mkdir -p /tmp/ccache + +# Create a local branch so the child Docker script won't complain +git branch -f jenkins-docker + +# Use image name based on Dockerfile checksum +DOCKER_IMAGE_NAME=grpc_jenkins_slave${docker_suffix}_`sha1sum tools/jenkins/grpc_jenkins_slave/Dockerfile | cut -f1 -d\ ` + +# Make sure docker image has been built. Should be instantaneous if so. +docker build -t $DOCKER_IMAGE_NAME tools/jenkins/grpc_jenkins_slave$docker_suffix + +# Make sure the CID file is gone. +rm -f docker.cid + +# Run tests inside docker +docker run \ + -e "RUN_TESTS_COMMAND=$RUN_TESTS_COMMAND" \ + -e "config=$config" \ + -e "arch=$arch" \ + -e CCACHE_DIR=/tmp/ccache \ + -i $TTY_FLAG \ + -v "$git_root:/var/local/jenkins/grpc" \ + -v /tmp/ccache:/tmp/ccache \ + -w /var/local/git/grpc \ + --cidfile=docker.cid \ + $DOCKER_IMAGE_NAME \ + bash -l /var/local/jenkins/grpc/tools/jenkins/docker_run_tests.sh || DOCKER_FAILED="true" + +DOCKER_CID=`cat docker.cid` + +if [ "$XML_REPORT" != "" ] +then + docker cp "$DOCKER_CID:/var/local/git/grpc/$XML_REPORT" $git_root +fi + +# remove the container, possibly killing it first +docker rm -f $DOCKER_CID || true + +if [ "$DOCKER_FAILED" != "" ] && [ "$XML_REPORT" == "" ] +then + exit 1 +fi diff --git a/tools/jenkins/docker_run_jenkins.sh b/tools/jenkins/docker_run_tests.sh index 0a5516c30d..781bff26b9 100755 --- a/tools/jenkins/docker_run_jenkins.sh +++ b/tools/jenkins/docker_run_tests.sh @@ -28,18 +28,17 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# This script is invoked by run_jekins.sh when piggy-backing into docker. +# This script is invoked by build_docker_and_run_tests.py inside a docker +# container. You should never need to call this script on your own. set -e export CONFIG=$config export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.5 -export CPPFLAGS=-I/tmp/prebuilt/include mkdir -p /var/local/git git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc -cd /var/local/git/grpc nvm use 0.12 rvm use ruby-2.1 -setarch $arch tools/run_tests/run_tests.py -t -c $config -l $language -x report.xml +$RUN_TESTS_COMMAND diff --git a/tools/jenkins/run_jenkins.sh b/tools/jenkins/run_jenkins.sh index 9ff588e8fa..a55f1de996 100755 --- a/tools/jenkins/run_jenkins.sh +++ b/tools/jenkins/run_jenkins.sh @@ -56,46 +56,8 @@ if [ "$platform" == "linux" ] then echo "building $language on Linux" - cd `dirname $0`/../.. - git_root=`pwd` - cd - + ./tools/run_tests/run_tests.py --use_docker -t -l $language -c $config -x report.xml || true - mkdir -p /tmp/ccache - - # Use image name based on Dockerfile checksum - DOCKER_IMAGE_NAME=grpc_jenkins_slave$docker_suffix_`sha1sum tools/jenkins/grpc_jenkins_slave/Dockerfile | cut -f1 -d\ ` - - # Make sure docker image has been built. Should be instantaneous if so. - docker build -t $DOCKER_IMAGE_NAME tools/jenkins/grpc_jenkins_slave$docker_suffix - - # Create a local branch so the child Docker script won't complain - git branch jenkins-docker - - # Make sure the CID file is gone. - rm -f docker.cid - - # Run tests inside docker - docker run \ - -e "config=$config" \ - -e "language=$language" \ - -e "arch=$arch" \ - -e CCACHE_DIR=/tmp/ccache \ - -i \ - -v "$git_root:/var/local/jenkins/grpc" \ - -v /tmp/ccache:/tmp/ccache \ - --cidfile=docker.cid \ - $DOCKER_IMAGE_NAME \ - bash -l /var/local/jenkins/grpc/tools/jenkins/docker_run_jenkins.sh || DOCKER_FAILED="true" - - DOCKER_CID=`cat docker.cid` - # forcefully kill the instance if it's still running, otherwise - # continue - # (failure to kill something that's already dead => things are dead) - docker kill $DOCKER_CID || true - docker cp $DOCKER_CID:/var/local/git/grpc/report.xml $git_root - # TODO(ctiller): why? - sleep 4 - docker rm $DOCKER_CID || true elif [ "$platform" == "interop" ] then python tools/run_tests/run_interops.py --language=$language diff --git a/tools/run_tests/port_server.py b/tools/run_tests/port_server.py index d14c829fe0..acb6deaae6 100755 --- a/tools/run_tests/port_server.py +++ b/tools/run_tests/port_server.py @@ -37,7 +37,6 @@ import os import socket import sys import time -import yaml argp = argparse.ArgumentParser(description='Server for httpcli_test') argp.add_argument('-p', '--port', default=12345, type=int) @@ -118,6 +117,9 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler): self.end_headers() self.wfile.write(_MY_VERSION) elif self.path == '/dump': + # yaml module is not installed on Macs and Windows machines by default + # so we import it lazily (/dump action is only used for debugging) + import yaml self.send_response(200) self.send_header('Content-Type', 'text/plain') self.end_headers() diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index c57fad9d0f..13d60e6f7b 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -493,12 +493,6 @@ _WINDOWS_CONFIG = { 'opt': 'Release', } -# parse command line -argp = argparse.ArgumentParser(description='Run grpc tests.') -argp.add_argument('-c', '--config', - choices=['all'] + sorted(_CONFIGS.keys()), - nargs='+', - default=_DEFAULT) def runs_per_test_type(arg_str): """Auxilary function to parse the "runs_per_test" flag. @@ -519,6 +513,13 @@ def runs_per_test_type(arg_str): except: msg = "'{}' isn't a positive integer or 'inf'".format(arg_str) raise argparse.ArgumentTypeError(msg) + +# parse command line +argp = argparse.ArgumentParser(description='Run grpc tests.') +argp.add_argument('-c', '--config', + choices=['all'] + sorted(_CONFIGS.keys()), + nargs='+', + default=_DEFAULT) argp.add_argument('-n', '--runs_per_test', default=1, type=runs_per_test_type, help='A positive integer or "inf". If "inf", all tests will run in an ' 'infinite loop. Especially useful in combination with "-f"') @@ -545,11 +546,48 @@ argp.add_argument('-S', '--stop_on_failure', default=False, action='store_const', const=True) +argp.add_argument('--use_docker', + default=False, + action='store_const', + const=True, + help="Run all the tests under docker. That provides " + + "additional isolation and prevents the need to installs " + + "language specific prerequisites. Only available on Linux.") argp.add_argument('-a', '--antagonists', default=0, type=int) argp.add_argument('-x', '--xml_report', default=None, type=str, help='Generates a JUnit-compatible XML report') args = argp.parse_args() +if args.use_docker: + if not args.travis: + print 'Seen --use_docker flag, will run tests under docker.' + print + print 'IMPORTANT: The changes you are testing need to be locally committed' + print 'because only the committed changes in the current branch will be' + print 'copied to the docker environment.' + time.sleep(5) + + child_argv = [ arg for arg in sys.argv if not arg == '--use_docker' ] + run_tests_cmd = 'tools/run_tests/run_tests.py %s' % " ".join(child_argv[1:]) + + # TODO(jtattermusch): revisit if we need special handling for arch here + # set arch command prefix in case we are working with different arch. + arch_env = os.getenv('arch') + if arch_env: + run_test_cmd = 'arch %s %s' % (arch_env, run_test_cmd) + + env = os.environ.copy() + env['RUN_TESTS_COMMAND'] = run_tests_cmd + if args.xml_report: + env['XML_REPORT'] = args.xml_report + if not args.travis: + env['TTY_FLAG'] = '-t' # enables Ctrl-C when not on Jenkins. + + subprocess.check_call(['tools/jenkins/build_docker_and_run_tests.sh'], + shell=True, + env=env) + sys.exit(0) + # grab config run_configs = set(_CONFIGS[cfg] for cfg in itertools.chain.from_iterable( diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 7acf0ff095..3696e2d1d8 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -12347,10 +12347,10 @@ "src/core/security/auth_filters.h", "src/core/security/base64.h", "src/core/security/credentials.h", + "src/core/security/handshake.h", "src/core/security/json_token.h", "src/core/security/jwt_verifier.h", "src/core/security/secure_endpoint.h", - "src/core/security/secure_transport_setup.h", "src/core/security/security_connector.h", "src/core/security/security_context.h", "src/core/statistics/census_interface.h", @@ -12564,14 +12564,14 @@ "src/core/security/credentials_posix.c", "src/core/security/credentials_win32.c", "src/core/security/google_default_credentials.c", + "src/core/security/handshake.c", + "src/core/security/handshake.h", "src/core/security/json_token.c", "src/core/security/json_token.h", "src/core/security/jwt_verifier.c", "src/core/security/jwt_verifier.h", "src/core/security/secure_endpoint.c", "src/core/security/secure_endpoint.h", - "src/core/security/secure_transport_setup.c", - "src/core/security/secure_transport_setup.h", "src/core/security/security_connector.c", "src/core/security/security_connector.h", "src/core/security/security_context.c", diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 0f8d3f9925..a09e813a5a 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -232,10 +232,10 @@ <ClInclude Include="..\..\..\src\core\security\auth_filters.h" /> <ClInclude Include="..\..\..\src\core\security\base64.h" /> <ClInclude Include="..\..\..\src\core\security\credentials.h" /> + <ClInclude Include="..\..\..\src\core\security\handshake.h" /> <ClInclude Include="..\..\..\src\core\security\json_token.h" /> <ClInclude Include="..\..\..\src\core\security\jwt_verifier.h" /> <ClInclude Include="..\..\..\src\core\security\secure_endpoint.h" /> - <ClInclude Include="..\..\..\src\core\security\secure_transport_setup.h" /> <ClInclude Include="..\..\..\src\core\security\security_connector.h" /> <ClInclude Include="..\..\..\src\core\security\security_context.h" /> <ClInclude Include="..\..\..\src\core\tsi\fake_transport_security.h" /> @@ -367,14 +367,14 @@ </ClCompile> <ClCompile Include="..\..\..\src\core\security\google_default_credentials.c"> </ClCompile> + <ClCompile Include="..\..\..\src\core\security\handshake.c"> + </ClCompile> <ClCompile Include="..\..\..\src\core\security\json_token.c"> </ClCompile> <ClCompile Include="..\..\..\src\core\security\jwt_verifier.c"> </ClCompile> <ClCompile Include="..\..\..\src\core\security\secure_endpoint.c"> </ClCompile> - <ClCompile Include="..\..\..\src\core\security\secure_transport_setup.c"> - </ClCompile> <ClCompile Include="..\..\..\src\core\security\security_connector.c"> </ClCompile> <ClCompile Include="..\..\..\src\core\security\security_context.c"> diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 64569c4c61..1538c33552 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -25,6 +25,9 @@ <ClCompile Include="..\..\..\src\core\security\google_default_credentials.c"> <Filter>src\core\security</Filter> </ClCompile> + <ClCompile Include="..\..\..\src\core\security\handshake.c"> + <Filter>src\core\security</Filter> + </ClCompile> <ClCompile Include="..\..\..\src\core\security\json_token.c"> <Filter>src\core\security</Filter> </ClCompile> @@ -34,9 +37,6 @@ <ClCompile Include="..\..\..\src\core\security\secure_endpoint.c"> <Filter>src\core\security</Filter> </ClCompile> - <ClCompile Include="..\..\..\src\core\security\secure_transport_setup.c"> - <Filter>src\core\security</Filter> - </ClCompile> <ClCompile Include="..\..\..\src\core\security\security_connector.c"> <Filter>src\core\security</Filter> </ClCompile> @@ -467,6 +467,9 @@ <ClInclude Include="..\..\..\src\core\security\credentials.h"> <Filter>src\core\security</Filter> </ClInclude> + <ClInclude Include="..\..\..\src\core\security\handshake.h"> + <Filter>src\core\security</Filter> + </ClInclude> <ClInclude Include="..\..\..\src\core\security\json_token.h"> <Filter>src\core\security</Filter> </ClInclude> @@ -476,9 +479,6 @@ <ClInclude Include="..\..\..\src\core\security\secure_endpoint.h"> <Filter>src\core\security</Filter> </ClInclude> - <ClInclude Include="..\..\..\src\core\security\secure_transport_setup.h"> - <Filter>src\core\security</Filter> - </ClInclude> <ClInclude Include="..\..\..\src\core\security\security_connector.h"> <Filter>src\core\security</Filter> </ClInclude> |