diff options
Diffstat (limited to 'src')
53 files changed, 415 insertions, 257 deletions
diff --git a/src/core/channel/compress_filter.c b/src/core/channel/compress_filter.c index c997a074a7..cc8e191628 100644 --- a/src/core/channel/compress_filter.c +++ b/src/core/channel/compress_filter.c @@ -39,11 +39,11 @@ #include <grpc/support/log.h> #include <grpc/support/slice_buffer.h> -#include "src/core/channel/compress_filter.h" #include "src/core/channel/channel_args.h" -#include "src/core/profiling/timers.h" +#include "src/core/channel/compress_filter.h" #include "src/core/compression/algorithm_metadata.h" #include "src/core/compression/message_compress.h" +#include "src/core/profiling/timers.h" #include "src/core/support/string.h" #include "src/core/transport/static_metadata.h" diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index b9a30cdaf2..65cfb778bb 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -31,12 +31,12 @@ */ #include "src/core/channel/http_client_filter.h" -#include <string.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include "src/core/support/string.h" +#include <string.h> #include "src/core/profiling/timers.h" +#include "src/core/support/string.h" #include "src/core/transport/static_metadata.h" typedef struct call_data { diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c index e7b8e42819..647621cc4f 100644 --- a/src/core/channel/http_server_filter.c +++ b/src/core/channel/http_server_filter.c @@ -33,9 +33,9 @@ #include "src/core/channel/http_server_filter.h" -#include <string.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include <string.h> #include "src/core/profiling/timers.h" #include "src/core/transport/static_metadata.h" diff --git a/src/core/httpcli/httpcli_security_connector.c b/src/core/httpcli/httpcli_security_connector.c index fc6699c918..a5aa551373 100644 --- a/src/core/httpcli/httpcli_security_connector.c +++ b/src/core/httpcli/httpcli_security_connector.c @@ -68,7 +68,7 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, tsi_result result = TSI_OK; tsi_handshaker *handshaker; if (c->handshaker_factory == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL); + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL); return; } result = tsi_ssl_handshaker_factory_create_handshaker( @@ -76,7 +76,7 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", tsi_result_to_string(result)); - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL); + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb, user_data); @@ -149,7 +149,6 @@ typedef struct { static void on_secure_transport_setup_done(grpc_exec_ctx *exec_ctx, void *rp, grpc_security_status status, - grpc_endpoint *wrapped_endpoint, grpc_endpoint *secure_endpoint) { on_done_closure *c = rp; if (status != GRPC_SECURITY_OK) { diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c index 81c19ca797..00710d83bd 100644 --- a/src/core/iomgr/fd_posix.c +++ b/src/core/iomgr/fd_posix.c @@ -211,14 +211,21 @@ static int has_watchers(grpc_fd *fd) { } void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done, - const char *reason) { + int *release_fd, const char *reason) { fd->on_done_closure = on_done; - shutdown(fd->fd, SHUT_RDWR); + fd->released = release_fd != NULL; + if (!fd->released) { + shutdown(fd->fd, SHUT_RDWR); + } else { + *release_fd = fd->fd; + } gpr_mu_lock(&fd->mu); REF_BY(fd, 1, reason); /* remove active status, but keep referenced */ if (!has_watchers(fd)) { fd->closed = 1; - close(fd->fd); + if (!fd->released) { + close(fd->fd); + } grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, 1); } else { wake_all_watchers_locked(fd); @@ -410,7 +417,9 @@ void grpc_fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher, } if (grpc_fd_is_orphaned(fd) && !has_watchers(fd) && !fd->closed) { fd->closed = 1; - close(fd->fd); + if (!fd->released) { + close(fd->fd); + } grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, 1); } gpr_mu_unlock(&fd->mu); diff --git a/src/core/iomgr/fd_posix.h b/src/core/iomgr/fd_posix.h index d558fc9fe5..df4eb64d4c 100644 --- a/src/core/iomgr/fd_posix.h +++ b/src/core/iomgr/fd_posix.h @@ -62,6 +62,7 @@ struct grpc_fd { gpr_mu mu; int shutdown; int closed; + int released; /* The watcher list. @@ -107,11 +108,12 @@ grpc_fd *grpc_fd_create(int fd, const char *name); /* Releases fd to be asynchronously destroyed. on_done is called when the underlying file descriptor is definitely close()d. If on_done is NULL, no callback will be made. + If release_fd is not NULL, it's set to fd and fd will not be closed. Requires: *fd initialized; no outstanding notify_on_read or notify_on_write. MUST NOT be called with a pollset lock taken */ void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done, - const char *reason); + int *release_fd, const char *reason); /* Begin polling on an fd. Registers that the given pollset is interested in this fd - so that if read diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c index c179248214..0a5577baea 100644 --- a/src/core/iomgr/pollset_posix.c +++ b/src/core/iomgr/pollset_posix.c @@ -613,7 +613,9 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx, GPR_TIMER_END("poll", 0); if (r < 0) { - gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); + if (errno != EINTR) { + gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); + } if (fd) { grpc_fd_end_poll(exec_ctx, &fd_watcher, 0, 0); } diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c index abd6315ca1..d9d24ee9a3 100644 --- a/src/core/iomgr/tcp_client_posix.c +++ b/src/core/iomgr/tcp_client_posix.c @@ -196,7 +196,7 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, int success) { finish: if (fd != NULL) { grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd); - grpc_fd_orphan(exec_ctx, fd, NULL, "tcp_client_orphan"); + grpc_fd_orphan(exec_ctx, fd, NULL, NULL, "tcp_client_orphan"); fd = NULL; } done = (--ac->refs == 0); @@ -265,7 +265,7 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure, if (errno != EWOULDBLOCK && errno != EINPROGRESS) { gpr_log(GPR_ERROR, "connect error to '%s': %s", addr_str, strerror(errno)); - grpc_fd_orphan(exec_ctx, fdobj, NULL, "tcp_client_connect_error"); + grpc_fd_orphan(exec_ctx, fdobj, NULL, NULL, "tcp_client_connect_error"); grpc_exec_ctx_enqueue(exec_ctx, closure, 0); goto done; } diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c index 915553d509..f3be41aa57 100644 --- a/src/core/iomgr/tcp_posix.c +++ b/src/core/iomgr/tcp_posix.c @@ -90,6 +90,8 @@ typedef struct { grpc_closure *read_cb; grpc_closure *write_cb; + grpc_closure *release_fd_cb; + int *release_fd; grpc_closure read_closure; grpc_closure write_closure; @@ -108,7 +110,8 @@ static void tcp_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { } static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { - grpc_fd_orphan(exec_ctx, tcp->em_fd, NULL, "tcp_unref_orphan"); + grpc_fd_orphan(exec_ctx, tcp->em_fd, tcp->release_fd_cb, tcp->release_fd, + "tcp_unref_orphan"); gpr_slice_buffer_destroy(&tcp->last_read_buffer); gpr_free(tcp->peer_string); gpr_free(tcp); @@ -452,6 +455,8 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size, tcp->fd = em_fd->fd; tcp->read_cb = NULL; tcp->write_cb = NULL; + tcp->release_fd_cb = NULL; + tcp->release_fd = NULL; tcp->incoming_buffer = NULL; tcp->slice_size = slice_size; tcp->iov_size = 1; @@ -468,4 +473,13 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size, return &tcp->base; } +void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + int *fd, grpc_closure *done) { + grpc_tcp *tcp = (grpc_tcp *)ep; + GPR_ASSERT(ep->vtable == &vtable); + tcp->release_fd = fd; + tcp->release_fd_cb = done; + TCP_UNREF(exec_ctx, tcp, "destroy"); +} + #endif diff --git a/src/core/iomgr/tcp_posix.h b/src/core/iomgr/tcp_posix.h index 40b3ae2679..b554983ae1 100644 --- a/src/core/iomgr/tcp_posix.h +++ b/src/core/iomgr/tcp_posix.h @@ -56,4 +56,10 @@ extern int grpc_tcp_trace; grpc_endpoint *grpc_tcp_create(grpc_fd *fd, size_t read_slice_size, const char *peer_string); +/* Destroy the tcp endpoint without closing its fd. *fd will be set and done + * will be called when the endpoint is destroyed. + * Requires: ep must be a tcp endpoint and fd must not be NULL. */ +void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + int *fd, grpc_closure *done); + #endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_POSIX_H */ diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 0ece77c4e8..a89ee02d34 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -193,7 +193,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { } sp->destroyed_closure.cb = destroyed_port; sp->destroyed_closure.cb_arg = s; - grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, + grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, "tcp_listener_shutdown"); } gpr_mu_unlock(&s->mu); diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c index 9903e970e6..782fbd9f46 100644 --- a/src/core/iomgr/udp_server.c +++ b/src/core/iomgr/udp_server.c @@ -179,7 +179,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { } sp->destroyed_closure.cb = destroyed_port; sp->destroyed_closure.cb_arg = s; - grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, + grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, "udp_listener_shutdown"); } gpr_mu_unlock(&s->mu); diff --git a/src/core/iomgr/workqueue_posix.c b/src/core/iomgr/workqueue_posix.c index c087b887b8..2e30178131 100644 --- a/src/core/iomgr/workqueue_posix.c +++ b/src/core/iomgr/workqueue_posix.c @@ -115,7 +115,7 @@ static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, int success) { /* HACK: let wakeup_fd code know that we stole the fd */ workqueue->wakeup_fd.read_fd = 0; grpc_wakeup_fd_destroy(&workqueue->wakeup_fd); - grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, "destroy"); + grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, NULL, "destroy"); gpr_free(workqueue); } else { gpr_mu_lock(&workqueue->mu); diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index cd4b39fa52..b1fd733c91 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -39,11 +39,11 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include "src/core/support/string.h" #include "src/core/channel/channel_stack.h" -#include "src/core/security/security_context.h" -#include "src/core/security/security_connector.h" #include "src/core/security/credentials.h" +#include "src/core/security/security_connector.h" +#include "src/core/security/security_context.h" +#include "src/core/support/string.h" #include "src/core/surface/call.h" #include "src/core/transport/static_metadata.h" @@ -62,7 +62,7 @@ typedef struct { grpc_transport_stream_op op; gpr_uint8 security_context_set; grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT]; - char *service_url; + grpc_auth_metadata_context auth_md_context; } call_data; /* We can have a per-channel credentials. */ @@ -70,11 +70,20 @@ typedef struct { grpc_channel_security_connector *security_connector; } channel_data; -static void reset_service_url(call_data *calld) { - if (calld->service_url != NULL) { - gpr_free(calld->service_url); - calld->service_url = NULL; +static void reset_auth_metadata_context( + grpc_auth_metadata_context *auth_md_context) { + if (auth_md_context->service_url != NULL) { + gpr_free((char *)auth_md_context->service_url); + auth_md_context->service_url = NULL; + } + if (auth_md_context->method_name != NULL) { + gpr_free((char *)auth_md_context->method_name); + auth_md_context->method_name = NULL; } + GRPC_AUTH_CONTEXT_UNREF( + (grpc_auth_context *)auth_md_context->channel_auth_context, + "grpc_auth_metadata_context"); + auth_md_context->channel_auth_context = NULL; } static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, @@ -94,7 +103,7 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data, grpc_transport_stream_op *op = &calld->op; grpc_metadata_batch *mdb; size_t i; - reset_service_url(calld); + reset_auth_metadata_context(&calld->auth_md_context); if (status != GRPC_CREDENTIALS_OK) { bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED, "Credentials failed to get metadata."); @@ -112,9 +121,13 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data, grpc_call_next_op(exec_ctx, elem, op); } -void build_service_url(const char *url_scheme, call_data *calld) { +void build_auth_metadata_context(grpc_security_connector *sc, + call_data *calld) { char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method)); char *last_slash = strrchr(service, '/'); + char *method_name = NULL; + char *service_url = NULL; + reset_auth_metadata_context(&calld->auth_md_context); if (last_slash == NULL) { gpr_log(GPR_ERROR, "No '/' found in fully qualified method name"); service[0] = '\0'; @@ -123,11 +136,16 @@ void build_service_url(const char *url_scheme, call_data *calld) { service[1] = '\0'; } else { *last_slash = '\0'; + method_name = gpr_strdup(last_slash + 1); } - if (url_scheme == NULL) url_scheme = ""; - reset_service_url(calld); - gpr_asprintf(&calld->service_url, "%s://%s%s", url_scheme, + if (method_name == NULL) method_name = gpr_strdup(""); + gpr_asprintf(&service_url, "%s://%s%s", + sc->url_scheme == NULL ? "" : sc->url_scheme, grpc_mdstr_as_c_string(calld->host), service); + calld->auth_md_context.service_url = service_url; + calld->auth_md_context.method_name = method_name; + calld->auth_md_context.channel_auth_context = + GRPC_AUTH_CONTEXT_REF(sc->auth_context, "grpc_auth_metadata_context"); gpr_free(service); } @@ -161,12 +179,12 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx, call_creds_has_md ? ctx->creds : channel_call_creds); } - build_service_url(chand->security_connector->base.url_scheme, calld); + build_auth_metadata_context(&chand->security_connector->base, calld); calld->op = *op; /* Copy op (originates from the caller's stack). */ GPR_ASSERT(calld->pollset); - grpc_call_credentials_get_request_metadata(exec_ctx, calld->creds, - calld->pollset, calld->service_url, - on_credentials_metadata, elem); + grpc_call_credentials_get_request_metadata( + exec_ctx, calld->creds, calld->pollset, calld->auth_md_context, + on_credentials_metadata, elem); } static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data, @@ -280,7 +298,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, if (calld->method != NULL) { GRPC_MDSTR_UNREF(calld->method); } - reset_service_url(calld); + reset_auth_metadata_context(&calld->auth_md_context); } /* Constructor for channel_data */ diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index f7a2e73785..543c75044b 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -33,16 +33,16 @@ #include "src/core/security/credentials.h" -#include <string.h> #include <stdio.h> +#include <string.h> #include "src/core/channel/channel_args.h" #include "src/core/channel/http_client_filter.h" -#include "src/core/json/json.h" #include "src/core/httpcli/httpcli.h" #include "src/core/iomgr/iomgr.h" -#include "src/core/surface/api_trace.h" +#include "src/core/json/json.h" #include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" #include <grpc/support/alloc.h> #include <grpc/support/log.h> @@ -116,19 +116,17 @@ void grpc_call_credentials_release(grpc_call_credentials *creds) { grpc_call_credentials_unref(creds); } -void grpc_call_credentials_get_request_metadata(grpc_exec_ctx *exec_ctx, - grpc_call_credentials *creds, - grpc_pollset *pollset, - const char *service_url, - grpc_credentials_metadata_cb cb, - void *user_data) { +void grpc_call_credentials_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { if (creds == NULL || creds->vtable->get_request_metadata == NULL) { if (cb != NULL) { cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); } return; } - creds->vtable->get_request_metadata(exec_ctx, creds, pollset, service_url, cb, + creds->vtable->get_request_metadata(exec_ctx, creds, pollset, context, cb, user_data); } @@ -429,7 +427,7 @@ static void jwt_destruct(grpc_call_credentials *creds) { static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, + grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data) { grpc_service_account_jwt_access_credentials *c = @@ -442,7 +440,7 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx, { gpr_mu_lock(&c->cache_mu); if (c->cached.service_url != NULL && - strcmp(c->cached.service_url, service_url) == 0 && + strcmp(c->cached.service_url, context.service_url) == 0 && c->cached.jwt_md != NULL && (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now(GPR_CLOCK_REALTIME)), @@ -457,14 +455,15 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx, /* Generate a new jwt. */ gpr_mu_lock(&c->cache_mu); jwt_reset_cache(c); - jwt = grpc_jwt_encode_and_sign(&c->key, service_url, c->jwt_lifetime, NULL); + jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url, + c->jwt_lifetime, NULL); if (jwt != NULL) { char *md_value; gpr_asprintf(&md_value, "Bearer %s", jwt); gpr_free(jwt); c->cached.jwt_expiration = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); - c->cached.service_url = gpr_strdup(service_url); + c->cached.service_url = gpr_strdup(context.service_url); c->cached.jwt_md = grpc_credentials_md_store_create(1); grpc_credentials_md_store_add_cstrings( c->cached.jwt_md, GRPC_AUTHORIZATION_METADATA_KEY, md_value); @@ -649,7 +648,7 @@ static void on_oauth2_token_fetcher_http_response( static void oauth2_token_fetcher_get_request_metadata( grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, - grpc_pollset *pollset, const char *service_url, + grpc_pollset *pollset, grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data) { grpc_oauth2_token_fetcher_credentials *c = (grpc_oauth2_token_fetcher_credentials *)creds; @@ -804,12 +803,10 @@ static void on_simulated_token_fetch_done(void *user_data) { grpc_exec_ctx_finish(&exec_ctx); } -static void md_only_test_get_request_metadata(grpc_exec_ctx *exec_ctx, - grpc_call_credentials *creds, - grpc_pollset *pollset, - const char *service_url, - grpc_credentials_metadata_cb cb, - void *user_data) { +static void md_only_test_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds; if (c->is_async) { @@ -846,12 +843,10 @@ static void access_token_destruct(grpc_call_credentials *creds) { grpc_credentials_md_store_unref(c->access_token_md); } -static void access_token_get_request_metadata(grpc_exec_ctx *exec_ctx, - grpc_call_credentials *creds, - grpc_pollset *pollset, - const char *service_url, - grpc_credentials_metadata_cb cb, - void *user_data) { +static void access_token_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds; cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK); } @@ -932,7 +927,7 @@ typedef struct { grpc_composite_call_credentials *composite_creds; size_t creds_index; grpc_credentials_md_store *md_elems; - char *service_url; + grpc_auth_metadata_context auth_md_context; void *user_data; grpc_pollset *pollset; grpc_credentials_metadata_cb cb; @@ -950,7 +945,6 @@ static void composite_call_destruct(grpc_call_credentials *creds) { static void composite_call_md_context_destroy( grpc_composite_call_credentials_metadata_context *ctx) { grpc_credentials_md_store_unref(ctx->md_elems); - if (ctx->service_url != NULL) gpr_free(ctx->service_url); gpr_free(ctx); } @@ -978,9 +972,9 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data, if (ctx->creds_index < ctx->composite_creds->inner.num_creds) { grpc_call_credentials *inner_creds = ctx->composite_creds->inner.creds_array[ctx->creds_index++]; - grpc_call_credentials_get_request_metadata(exec_ctx, inner_creds, - ctx->pollset, ctx->service_url, - composite_call_metadata_cb, ctx); + grpc_call_credentials_get_request_metadata( + exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context, + composite_call_metadata_cb, ctx); return; } @@ -990,26 +984,24 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data, composite_call_md_context_destroy(ctx); } -static void composite_call_get_request_metadata(grpc_exec_ctx *exec_ctx, - grpc_call_credentials *creds, - grpc_pollset *pollset, - const char *service_url, - grpc_credentials_metadata_cb cb, - void *user_data) { +static void composite_call_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context auth_md_context, + grpc_credentials_metadata_cb cb, void *user_data) { grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds; grpc_composite_call_credentials_metadata_context *ctx; ctx = gpr_malloc(sizeof(grpc_composite_call_credentials_metadata_context)); memset(ctx, 0, sizeof(grpc_composite_call_credentials_metadata_context)); - ctx->service_url = gpr_strdup(service_url); + ctx->auth_md_context = auth_md_context; ctx->user_data = user_data; ctx->cb = cb; ctx->composite_creds = c; ctx->pollset = pollset; ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds); grpc_call_credentials_get_request_metadata( - exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset, service_url, - composite_call_metadata_cb, ctx); + exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset, + auth_md_context, composite_call_metadata_cb, ctx); } static grpc_call_credentials_vtable composite_call_credentials_vtable = { @@ -1103,7 +1095,7 @@ static void iam_destruct(grpc_call_credentials *creds) { static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, + grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data) { grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds; @@ -1192,7 +1184,7 @@ static void plugin_md_request_metadata_ready(void *request, static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, + grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data) { grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds; @@ -1201,7 +1193,7 @@ static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx, memset(request, 0, sizeof(*request)); request->user_data = user_data; request->cb = cb; - c->plugin.get_metadata(c->plugin.state, service_url, + c->plugin.get_metadata(c->plugin.state, context, plugin_md_request_metadata_ready, request); } else { cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); @@ -1218,7 +1210,7 @@ grpc_call_credentials *grpc_metadata_credentials_create_from_plugin( (reserved)); GPR_ASSERT(reserved == NULL); memset(c, 0, sizeof(*c)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_METADATA_PLUGIN; + c->base.type = plugin.type; c->base.vtable = &plugin_vtable; gpr_ref_init(&c->base.refcount, 1); c->plugin = plugin; diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h index 132060910e..6d45895e77 100644 --- a/src/core/security/credentials.h +++ b/src/core/security/credentials.h @@ -59,7 +59,6 @@ typedef enum { "FakeTransportSecurity" #define GRPC_CALL_CREDENTIALS_TYPE_OAUTH2 "Oauth2" -#define GRPC_CALL_CREDENTIALS_TYPE_METADATA_PLUGIN "Plugin" #define GRPC_CALL_CREDENTIALS_TYPE_JWT "Jwt" #define GRPC_CALL_CREDENTIALS_TYPE_IAM "Iam" #define GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE "Composite" @@ -162,7 +161,7 @@ typedef struct { void (*destruct)(grpc_call_credentials *c); void (*get_request_metadata)(grpc_exec_ctx *exec_ctx, grpc_call_credentials *c, grpc_pollset *pollset, - const char *service_url, + grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data); } grpc_call_credentials_vtable; @@ -175,12 +174,10 @@ struct grpc_call_credentials { grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds); void grpc_call_credentials_unref(grpc_call_credentials *creds); -void grpc_call_credentials_get_request_metadata(grpc_exec_ctx *exec_ctx, - grpc_call_credentials *creds, - grpc_pollset *pollset, - const char *service_url, - grpc_credentials_metadata_cb cb, - void *user_data); +void grpc_call_credentials_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data); typedef struct { grpc_call_credentials **creds_array; diff --git a/src/core/security/handshake.c b/src/core/security/handshake.c index adbdd0b40e..6734187fce 100644 --- a/src/core/security/handshake.c +++ b/src/core/security/handshake.c @@ -64,12 +64,39 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx, static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *setup, int success); +static void security_connector_remove_handshake(grpc_security_handshake *h) { + grpc_security_connector_handshake_list *node; + grpc_security_connector_handshake_list *tmp; + grpc_security_connector *sc = h->connector; + gpr_mu_lock(&sc->mu); + node = sc->handshaking_handshakes; + if (node && node->handshake == h) { + sc->handshaking_handshakes = node->next; + gpr_free(node); + gpr_mu_unlock(&sc->mu); + return; + } + while (node) { + if (node->next->handshake == h) { + tmp = node->next; + node->next = node->next->next; + gpr_free(tmp); + gpr_mu_unlock(&sc->mu); + return; + } + node = node->next; + } + gpr_mu_unlock(&sc->mu); +} + static void security_handshake_done(grpc_exec_ctx *exec_ctx, grpc_security_handshake *h, int is_success) { + if (!h->connector->is_client_side) { + security_connector_remove_handshake(h); + } if (is_success) { - h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->wrapped_endpoint, - h->secure_endpoint); + h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->secure_endpoint); } else { if (h->secure_endpoint != NULL) { grpc_endpoint_shutdown(exec_ctx, h->secure_endpoint); @@ -77,8 +104,7 @@ static void security_handshake_done(grpc_exec_ctx *exec_ctx, } else { grpc_endpoint_destroy(exec_ctx, h->wrapped_endpoint); } - h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, h->wrapped_endpoint, - NULL); + h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL); } if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker); if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer); @@ -268,6 +294,7 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb, void *user_data) { + grpc_security_connector_handshake_list *handshake_node; grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake)); memset(h, 0, sizeof(grpc_security_handshake)); h->handshaker = handshaker; @@ -284,5 +311,19 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, gpr_slice_buffer_init(&h->left_overs); gpr_slice_buffer_init(&h->outgoing); gpr_slice_buffer_init(&h->incoming); + if (!connector->is_client_side) { + handshake_node = gpr_malloc(sizeof(grpc_security_connector_handshake_list)); + handshake_node->handshake = h; + gpr_mu_lock(&connector->mu); + handshake_node->next = connector->handshaking_handshakes; + connector->handshaking_handshakes = handshake_node; + gpr_mu_unlock(&connector->mu); + } send_handshake_bytes_to_peer(exec_ctx, h); } + +void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, + void *handshake) { + grpc_security_handshake *h = handshake; + grpc_endpoint_shutdown(exec_ctx, h->wrapped_endpoint); +} diff --git a/src/core/security/handshake.h b/src/core/security/handshake.h index 28eaa79dc3..44215d16ef 100644 --- a/src/core/security/handshake.h +++ b/src/core/security/handshake.h @@ -45,4 +45,6 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, grpc_security_handshake_done_cb cb, void *user_data); +void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake); + #endif /* GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H */ diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c index 3c54a4deae..8c6ab0b8a4 100644 --- a/src/core/security/security_connector.c +++ b/src/core/security/security_connector.c @@ -102,13 +102,29 @@ const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer, return NULL; } +void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx, + grpc_security_connector *connector) { + grpc_security_connector_handshake_list *tmp; + if (!connector->is_client_side) { + gpr_mu_lock(&connector->mu); + while (connector->handshaking_handshakes) { + tmp = connector->handshaking_handshakes; + grpc_security_handshake_shutdown( + exec_ctx, connector->handshaking_handshakes->handshake); + connector->handshaking_handshakes = tmp->next; + gpr_free(tmp); + } + gpr_mu_unlock(&connector->mu); + } +} + void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb, void *user_data) { if (sc == NULL || nonsecure_endpoint == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL); + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL); } else { sc->vtable->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data); } @@ -219,6 +235,7 @@ static void fake_channel_destroy(grpc_security_connector *sc) { static void fake_server_destroy(grpc_security_connector *sc) { GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector"); + gpr_mu_destroy(&sc->mu); gpr_free(sc); } @@ -319,6 +336,7 @@ grpc_security_connector *grpc_fake_server_security_connector_create(void) { c->is_client_side = 0; c->vtable = &fake_server_vtable; c->url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; + gpr_mu_init(&c->mu); return c; } @@ -354,10 +372,12 @@ static void ssl_channel_destroy(grpc_security_connector *sc) { static void ssl_server_destroy(grpc_security_connector *sc) { grpc_ssl_server_security_connector *c = (grpc_ssl_server_security_connector *)sc; + if (c->handshaker_factory != NULL) { tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); } GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector"); + gpr_mu_destroy(&sc->mu); gpr_free(sc); } @@ -390,7 +410,7 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, : c->target_name, &handshaker); if (status != GRPC_SECURITY_OK) { - cb(exec_ctx, user_data, status, nonsecure_endpoint, NULL); + cb(exec_ctx, user_data, status, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb, user_data); @@ -408,7 +428,7 @@ static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx, grpc_security_status status = ssl_create_handshaker(c->handshaker_factory, 0, NULL, &handshaker); if (status != GRPC_SECURITY_OK) { - cb(exec_ctx, user_data, status, nonsecure_endpoint, NULL); + cb(exec_ctx, user_data, status, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb, user_data); @@ -691,6 +711,7 @@ grpc_security_status grpc_ssl_server_security_connector_create( *sc = NULL; goto error; } + gpr_mu_init(&c->base.mu); *sc = &c->base; gpr_free((void *)alpn_protocol_strings); gpr_free(alpn_protocol_string_lengths); diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h index c5f00c5563..7edb05a662 100644 --- a/src/core/security/security_connector.h +++ b/src/core/security/security_connector.h @@ -67,7 +67,6 @@ typedef void (*grpc_security_check_cb)(grpc_exec_ctx *exec_ctx, void *user_data, typedef void (*grpc_security_handshake_done_cb)(grpc_exec_ctx *exec_ctx, void *user_data, grpc_security_status status, - grpc_endpoint *wrapped_endpoint, grpc_endpoint *secure_endpoint); typedef struct { @@ -80,12 +79,22 @@ typedef struct { void *user_data); } grpc_security_connector_vtable; +typedef struct grpc_security_connector_handshake_list { + void *handshake; + struct grpc_security_connector_handshake_list *next; +} grpc_security_connector_handshake_list; + struct grpc_security_connector { const grpc_security_connector_vtable *vtable; gpr_refcount refcount; int is_client_side; const char *url_scheme; grpc_auth_context *auth_context; /* Populated after the peer is checked. */ + /* Used on server side only. */ + /* TODO(yangg) maybe create a grpc_server_security_connector with these */ + gpr_mu mu; + grpc_security_connector_handshake_list *handshaking_handshakes; + const grpc_channel_args *channel_args; }; /* Refcounting. */ @@ -126,6 +135,9 @@ grpc_security_status grpc_security_connector_check_peer( grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb, void *user_data); +void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx, + grpc_security_connector *connector); + /* Util to encapsulate the connector in a channel arg. */ grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc); diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index 14a5d0fef6..6bda8a360c 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -52,17 +52,11 @@ #include <grpc/support/sync.h> #include <grpc/support/useful.h> -typedef struct tcp_endpoint_list { - grpc_endpoint *tcp_endpoint; - struct tcp_endpoint_list *next; -} tcp_endpoint_list; - typedef struct grpc_server_secure_state { grpc_server *server; grpc_tcp_server *tcp; grpc_security_connector *sc; grpc_server_credentials *creds; - tcp_endpoint_list *handshaking_tcp_endpoints; int is_shutdown; gpr_mu mu; gpr_refcount refcount; @@ -103,52 +97,28 @@ static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep, grpc_channel_args_destroy(args_copy); } -static int remove_tcp_from_list_locked(grpc_server_secure_state *state, - grpc_endpoint *tcp) { - tcp_endpoint_list *node = state->handshaking_tcp_endpoints; - tcp_endpoint_list *tmp = NULL; - if (node && node->tcp_endpoint == tcp) { - state->handshaking_tcp_endpoints = state->handshaking_tcp_endpoints->next; - gpr_free(node); - return 0; - } - while (node) { - if (node->next->tcp_endpoint == tcp) { - tmp = node->next; - node->next = node->next->next; - gpr_free(tmp); - return 0; - } - node = node->next; - } - return -1; -} - static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, grpc_security_status status, - grpc_endpoint *wrapped_endpoint, grpc_endpoint *secure_endpoint) { grpc_server_secure_state *state = statep; grpc_transport *transport; if (status == GRPC_SECURITY_OK) { - gpr_mu_lock(&state->mu); - remove_tcp_from_list_locked(state, wrapped_endpoint); - if (!state->is_shutdown) { - transport = grpc_create_chttp2_transport( - exec_ctx, grpc_server_get_channel_args(state->server), - secure_endpoint, 0); - setup_transport(exec_ctx, state, transport); - grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); - } else { - /* We need to consume this here, because the server may already have gone - * away. */ - grpc_endpoint_destroy(exec_ctx, secure_endpoint); + if (secure_endpoint) { + gpr_mu_lock(&state->mu); + if (!state->is_shutdown) { + transport = grpc_create_chttp2_transport( + exec_ctx, grpc_server_get_channel_args(state->server), + secure_endpoint, 0); + setup_transport(exec_ctx, state, transport); + grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); + } else { + /* We need to consume this here, because the server may already have + * gone away. */ + grpc_endpoint_destroy(exec_ctx, secure_endpoint); + } + gpr_mu_unlock(&state->mu); } - gpr_mu_unlock(&state->mu); } else { - gpr_mu_lock(&state->mu); - remove_tcp_from_list_locked(state, wrapped_endpoint); - gpr_mu_unlock(&state->mu); gpr_log(GPR_ERROR, "Secure transport failed with error %d", status); } state_unref(state); @@ -157,14 +127,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp) { grpc_server_secure_state *state = statep; - tcp_endpoint_list *node; state_ref(state); - node = gpr_malloc(sizeof(tcp_endpoint_list)); - node->tcp_endpoint = tcp; - gpr_mu_lock(&state->mu); - node->next = state->handshaking_tcp_endpoints; - state->handshaking_tcp_endpoints = node; - gpr_mu_unlock(&state->mu); grpc_security_connector_do_handshake(exec_ctx, state->sc, tcp, on_secure_handshake_done, state); } @@ -181,14 +144,7 @@ static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, int success) { grpc_server_secure_state *state = statep; state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg, success); - gpr_mu_lock(&state->mu); - while (state->handshaking_tcp_endpoints != NULL) { - grpc_endpoint_shutdown(exec_ctx, - state->handshaking_tcp_endpoints->tcp_endpoint); - remove_tcp_from_list_locked(state, - state->handshaking_tcp_endpoints->tcp_endpoint); - } - gpr_mu_unlock(&state->mu); + grpc_security_connector_shutdown(exec_ctx, state->sc); state_unref(state); } @@ -234,6 +190,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, creds->type); goto error; } + sc->channel_args = grpc_server_get_channel_args(server); /* resolve address */ resolved = grpc_blocking_resolve_address(addr, "https"); @@ -280,7 +237,6 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, state->sc = sc; state->creds = grpc_server_credentials_ref(creds); - state->handshaking_tcp_endpoints = NULL; state->is_shutdown = 0; gpr_mu_init(&state->mu); gpr_ref_init(&state->refcount, 1); diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 1dac6efa11..92f7e0ed47 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -916,7 +916,7 @@ static batch_control *allocate_batch_control(grpc_call *call) { return &call->active_batches[i]; } } - GPR_UNREACHABLE_CODE(return NULL); + return NULL; } static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data, diff --git a/src/core/surface/init.c b/src/core/surface/init.c index 04d68620f1..e0106d8f2b 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -58,6 +58,10 @@ #include "src/core/transport/chttp2_transport.h" #include "src/core/transport/connectivity_state.h" +#ifndef GRPC_DEFAULT_NAME_PREFIX +#define GRPC_DEFAULT_NAME_PREFIX "dns:///" +#endif + #define MAX_PLUGINS 128 static gpr_once g_basic_init = GPR_ONCE_INIT; @@ -97,7 +101,7 @@ void grpc_init(void) { grpc_lb_policy_registry_init(grpc_pick_first_lb_factory_create()); grpc_register_lb_policy(grpc_pick_first_lb_factory_create()); grpc_register_lb_policy(grpc_round_robin_lb_factory_create()); - grpc_resolver_registry_init("dns:///"); + grpc_resolver_registry_init(GRPC_DEFAULT_NAME_PREFIX); grpc_register_resolver_type(grpc_dns_resolver_factory_create()); grpc_register_resolver_type(grpc_ipv4_resolver_factory_create()); grpc_register_resolver_type(grpc_ipv6_resolver_factory_create()); diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index 826ab8e86c..863c905ea3 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -88,7 +88,6 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_security_status status, - grpc_endpoint *wrapped_endpoint, grpc_endpoint *secure_endpoint) { connector *c = arg; grpc_closure *notify; @@ -97,13 +96,11 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, memset(c->result, 0, sizeof(*c->result)); gpr_mu_unlock(&c->mu); } else if (status != GRPC_SECURITY_OK) { - GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint); 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); } else { - GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint); c->connecting_endpoint = NULL; gpr_mu_unlock(&c->mu); c->result->transport = grpc_create_chttp2_transport( diff --git a/src/core/transport/chttp2/frame_settings.c b/src/core/transport/chttp2/frame_settings.c index 395a2da452..d7c9f7ed69 100644 --- a/src/core/transport/chttp2/frame_settings.c +++ b/src/core/transport/chttp2/frame_settings.c @@ -36,27 +36,32 @@ #include <string.h> +#include <grpc/support/log.h> +#include <grpc/support/useful.h> + #include "src/core/debug/trace.h" #include "src/core/transport/chttp2/frame.h" +#include "src/core/transport/chttp2/http2_errors.h" #include "src/core/transport/chttp2_transport.h" -#include <grpc/support/log.h> -#include <grpc/support/useful.h> /* HTTP/2 mandated initial connection settings */ const grpc_chttp2_setting_parameters grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = { - {NULL, 0, 0, 0, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE}, + {NULL, 0, 0, 0, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, + GRPC_CHTTP2_PROTOCOL_ERROR}, {"HEADER_TABLE_SIZE", 4096, 0, 0xffffffff, - GRPC_CHTTP2_CLAMP_INVALID_VALUE}, - {"ENABLE_PUSH", 1, 0, 1, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE}, + GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, + {"ENABLE_PUSH", 1, 0, 1, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, + GRPC_CHTTP2_PROTOCOL_ERROR}, {"MAX_CONCURRENT_STREAMS", 0xffffffffu, 0, 0xffffffffu, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE}, - {"INITIAL_WINDOW_SIZE", 65535, 0, 0xffffffffu, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE}, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, + {"INITIAL_WINDOW_SIZE", 65535, 0, 0x7fffffffu, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, + GRPC_CHTTP2_FLOW_CONTROL_ERROR}, {"MAX_FRAME_SIZE", 16384, 16384, 16777215, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE}, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, {"MAX_HEADER_LIST_SIZE", 0xffffffffu, 0, 0xffffffffu, - GRPC_CHTTP2_CLAMP_INVALID_VALUE}, + GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, }; static gpr_uint8 *fill_header(gpr_uint8 *out, gpr_uint32 length, @@ -218,6 +223,10 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( GPR_CLAMP(parser->value, sp->min_value, sp->max_value); break; case GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE: + grpc_chttp2_goaway_append( + transport_parsing->last_incoming_stream_id, sp->error_value, + gpr_slice_from_static_string("HTTP2 settings error"), + &transport_parsing->qbuf); gpr_log(GPR_ERROR, "invalid value %u passed for %s", parser->value, sp->name); return GRPC_CHTTP2_CONNECTION_ERROR; diff --git a/src/core/transport/chttp2/frame_settings.h b/src/core/transport/chttp2/frame_settings.h index cf857dd602..e9c3c440b5 100644 --- a/src/core/transport/chttp2/frame_settings.h +++ b/src/core/transport/chttp2/frame_settings.h @@ -79,6 +79,7 @@ typedef struct { gpr_uint32 min_value; gpr_uint32 max_value; grpc_chttp2_invalid_value_behavior invalid_value_behavior; + gpr_uint32 error_value; } grpc_chttp2_setting_parameters; /* HTTP/2 mandated connection setting parameters */ diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c index 467e734cc3..eb2cb6b4c2 100644 --- a/src/core/transport/chttp2/parsing.c +++ b/src/core/transport/chttp2/parsing.c @@ -115,9 +115,6 @@ void grpc_chttp2_publish_reads( transport_parsing->incoming_stream_id; } - /* copy parsing qbuf to global qbuf */ - gpr_slice_buffer_move_into(&transport_parsing->qbuf, &transport_global->qbuf); - /* update global settings */ if (transport_parsing->settings_updated) { memcpy(transport_global->settings[GRPC_PEER_SETTINGS], diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 91c50dd2cb..6ba9db8348 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -1299,7 +1299,11 @@ static void recv_data(grpc_exec_ctx *exec_ctx, void *tp, int success) { ; GPR_TIMER_END("recv_data.parse", 0); gpr_mu_lock(&t->mu); + /* copy parsing qbuf to global qbuf */ + gpr_slice_buffer_move_into(&t->parsing.qbuf, &t->global.qbuf); if (i != t->read_buffer.count) { + unlock(exec_ctx, t); + lock(t); drop_connection(exec_ctx, t); } /* merge stream lists */ diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c index 56e83a0a75..4328bdd684 100644 --- a/src/core/transport/metadata.c +++ b/src/core/transport/metadata.c @@ -132,6 +132,7 @@ typedef struct mdtab_shard { /* hash seed: decided at initialization time */ static gpr_uint32 g_hash_seed; +static int g_forced_hash_seed = 0; /* linearly probed hash tables for static element lookup */ static grpc_mdstr *g_static_strtab[GRPC_STATIC_MDSTR_COUNT * 2]; @@ -144,9 +145,16 @@ static mdtab_shard g_mdtab_shard[MDTAB_SHARD_COUNT]; static void gc_mdtab(mdtab_shard *shard); +void grpc_test_only_set_metadata_hash_seed(gpr_uint32 seed) { + g_hash_seed = seed; + g_forced_hash_seed = 1; +} + void grpc_mdctx_global_init(void) { size_t i, j; - g_hash_seed = (gpr_uint32)gpr_now(GPR_CLOCK_REALTIME).tv_nsec; + if (!g_forced_hash_seed) { + g_hash_seed = (gpr_uint32)gpr_now(GPR_CLOCK_REALTIME).tv_nsec; + } g_static_strtab_maxprobe = 0; g_static_mdtab_maxprobe = 0; /* build static tables */ diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h index c1071e4e16..3d3efc682d 100644 --- a/src/core/transport/metadata.h +++ b/src/core/transport/metadata.h @@ -86,11 +86,7 @@ struct grpc_mdelem { /* there is a private part to this in metadata.c */ }; -/* Test only accessors to internal state - only for testing this code - do not - rely on it outside of metadata_test.c */ -size_t grpc_mdctx_get_mdtab_capacity_test_only(void); -size_t grpc_mdctx_get_mdtab_count_test_only(void); -size_t grpc_mdctx_get_mdtab_free_test_only(void); +void grpc_test_only_set_metadata_hash_seed(gpr_uint32 seed); /* Constructors for grpc_mdstr instances; take a variety of data types that clients may have handy */ diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index a1b9a3018e..96ae25b761 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -31,12 +31,13 @@ * */ -#include <grpc/support/log.h> #include <grpc++/channel.h> #include <grpc++/impl/grpc_library.h> #include <grpc++/support/channel_arguments.h> +#include <grpc/support/log.h> #include "src/cpp/client/create_channel_internal.h" #include "src/cpp/client/secure_credentials.h" +#include "src/cpp/common/secure_auth_context.h" namespace grpc { @@ -160,7 +161,7 @@ void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) { } void MetadataCredentialsPluginWrapper::GetMetadata( - void* wrapper, const char* service_url, + void* wrapper, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data) { GPR_ASSERT(wrapper); MetadataCredentialsPluginWrapper* w = @@ -171,18 +172,25 @@ void MetadataCredentialsPluginWrapper::GetMetadata( } if (w->plugin_->IsBlocking()) { w->thread_pool_->Add( - std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, - service_url, cb, user_data)); + std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, context, + cb, user_data)); } else { - w->InvokePlugin(service_url, cb, user_data); + w->InvokePlugin(context, cb, user_data); } } void MetadataCredentialsPluginWrapper::InvokePlugin( - const char* service_url, grpc_credentials_plugin_metadata_cb cb, + grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data) { std::multimap<grpc::string, grpc::string> metadata; - Status status = plugin_->GetMetadata(service_url, &metadata); + + // const_cast is safe since the SecureAuthContext does not take owndership and + // the object is passed as a const ref to plugin_->GetMetadata. + SecureAuthContext cpp_channel_auth_context( + const_cast<grpc_auth_context*>(context.channel_auth_context), false); + + Status status = plugin_->GetMetadata(context.service_url, context.method_name, + cpp_channel_auth_context, &metadata); std::vector<grpc_metadata> md; for (auto it = metadata.begin(); it != metadata.end(); ++it) { grpc_metadata md_entry; @@ -204,11 +212,12 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper( std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin( std::unique_ptr<MetadataCredentialsPlugin> plugin) { GrpcLibrary init; // To call grpc_init(). + const char* type = plugin->GetType(); MetadataCredentialsPluginWrapper* wrapper = new MetadataCredentialsPluginWrapper(std::move(plugin)); grpc_metadata_credentials_plugin c_plugin = { MetadataCredentialsPluginWrapper::GetMetadata, - MetadataCredentialsPluginWrapper::Destroy, wrapper}; + MetadataCredentialsPluginWrapper::Destroy, wrapper, type}; return WrapCallCredentials( grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); } diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index e9afa9e57f..cef59292dd 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -79,7 +79,7 @@ class SecureCallCredentials GRPC_FINAL : public CallCredentials { class MetadataCredentialsPluginWrapper GRPC_FINAL { public: static void Destroy(void* wrapper); - static void GetMetadata(void* wrapper, const char* service_url, + static void GetMetadata(void* wrapper, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data); @@ -87,7 +87,7 @@ class MetadataCredentialsPluginWrapper GRPC_FINAL { std::unique_ptr<MetadataCredentialsPlugin> plugin); private: - void InvokePlugin(const char* service_url, + void InvokePlugin(grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data); std::unique_ptr<ThreadPoolInterface> thread_pool_; std::unique_ptr<MetadataCredentialsPlugin> plugin_; diff --git a/src/cpp/client/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 50422d06c9..90cd5136af 100644 --- a/src/cpp/client/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -62,7 +62,9 @@ ChannelArguments::ChannelArguments(const ChannelArguments& other) break; case GRPC_ARG_POINTER: ap.value.pointer = a->value.pointer; - ap.value.pointer.p = a->value.pointer.copy(ap.value.pointer.p); + ap.value.pointer.p = a->value.pointer.copy + ? a->value.pointer.copy(ap.value.pointer.p) + : ap.value.pointer.p; break; } args_.push_back(ap); @@ -89,6 +91,17 @@ void ChannelArguments::SetInt(const grpc::string& key, int value) { args_.push_back(arg); } +void ChannelArguments::SetPointer(const grpc::string& key, void* value) { + grpc_arg arg; + arg.type = GRPC_ARG_POINTER; + strings_.push_back(key); + arg.key = const_cast<char*>(strings_.back().c_str()); + arg.value.pointer.p = value; + arg.value.pointer.copy = nullptr; + arg.value.pointer.destroy = nullptr; + args_.push_back(arg); +} + void ChannelArguments::SetString(const grpc::string& key, const grpc::string& value) { grpc_arg arg; diff --git a/src/cpp/client/secure_channel_arguments.cc b/src/cpp/common/secure_channel_arguments.cc index e17d3b58b0..e17d3b58b0 100644 --- a/src/cpp/client/secure_channel_arguments.cc +++ b/src/cpp/common/secure_channel_arguments.cc diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 695e811654..878775bbee 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -51,6 +51,22 @@ namespace grpc { +class DefaultGlobalCallbacks GRPC_FINAL : public Server::GlobalCallbacks { + public: + void PreSynchronousRequest(ServerContext* context) GRPC_OVERRIDE {} + void PostSynchronousRequest(ServerContext* context) GRPC_OVERRIDE {} +}; + +static Server::GlobalCallbacks* g_callbacks = nullptr; +static gpr_once g_once_init_callbacks = GPR_ONCE_INIT; + +static void InitGlobalCallbacks() { + if (g_callbacks == nullptr) { + static DefaultGlobalCallbacks default_global_callbacks; + g_callbacks = &default_global_callbacks; + } +} + class Server::UnimplementedAsyncRequestContext { protected: UnimplementedAsyncRequestContext() : generic_stream_(&server_context_) {} @@ -220,8 +236,10 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag { void Run() { ctx_.BeginCompletionOp(&call_); + g_callbacks->PreSynchronousRequest(&ctx_); method_->handler()->RunHandler(MethodHandler::HandlerParameter( &call_, &ctx_, request_payload_, call_.max_message_size())); + g_callbacks->PostSynchronousRequest(&ctx_); request_payload_ = nullptr; void* ignored_tag; bool ignored_ok; @@ -251,38 +269,24 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag { grpc_completion_queue* cq_; }; -static grpc_server* CreateServer( - int max_message_size, const grpc_compression_options& compression_options) { - grpc_arg args[2]; - size_t args_idx = 0; - if (max_message_size > 0) { - args[args_idx].type = GRPC_ARG_INTEGER; - args[args_idx].key = const_cast<char*>(GRPC_ARG_MAX_MESSAGE_LENGTH); - args[args_idx].value.integer = max_message_size; - args_idx++; - } - - args[args_idx].type = GRPC_ARG_INTEGER; - args[args_idx].key = const_cast<char*>(GRPC_COMPRESSION_ALGORITHM_STATE_ARG); - args[args_idx].value.integer = compression_options.enabled_algorithms_bitset; - args_idx++; - - grpc_channel_args channel_args = {args_idx, args}; +static grpc_server* CreateServer(const ChannelArguments& args) { + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); return grpc_server_create(&channel_args, nullptr); } Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, - int max_message_size, - grpc_compression_options compression_options) + int max_message_size, const ChannelArguments& args) : max_message_size_(max_message_size), started_(false), shutdown_(false), num_running_cb_(0), sync_methods_(new std::list<SyncRequest>), has_generic_service_(false), - server_(CreateServer(max_message_size, compression_options)), + server_(CreateServer(args)), thread_pool_(thread_pool), thread_pool_owned_(thread_pool_owned) { + gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks); grpc_server_register_completion_queue(server_, cq_.cq(), nullptr); } @@ -304,6 +308,12 @@ Server::~Server() { delete sync_methods_; } +void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { + GPR_ASSERT(g_callbacks == nullptr); + GPR_ASSERT(callbacks != nullptr); + g_callbacks = callbacks; +} + bool Server::RegisterService(const grpc::string* host, RpcService* service) { for (int i = 0; i < service->GetMethodCount(); ++i) { RpcServiceMethod* method = service->GetMethod(i); diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index b8094aa8f6..26c0724a30 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -84,6 +84,10 @@ void ServerBuilder::RegisterAsyncGenericService(AsyncGenericService* service) { generic_service_ = service; } +void ServerBuilder::SetOption(std::unique_ptr<ServerBuilderOption> option) { + options_.push_back(std::move(option)); +} + void ServerBuilder::AddListeningPort(const grpc::string& addr, std::shared_ptr<ServerCredentials> creds, int* selected_port) { @@ -101,9 +105,17 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() { thread_pool_ = CreateDefaultThreadPool(); thread_pool_owned = true; } - std::unique_ptr<Server> server(new Server(thread_pool_, thread_pool_owned, - max_message_size_, - compression_options_)); + ChannelArguments args; + for (auto option = options_.begin(); option != options_.end(); ++option) { + (*option)->UpdateArguments(&args); + } + if (max_message_size_ > 0) { + args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_); + } + args.SetInt(GRPC_COMPRESSION_ALGORITHM_STATE_ARG, + compression_options_.enabled_algorithms_bitset); + std::unique_ptr<Server> server( + new Server(thread_pool_, thread_pool_owned, max_message_size_, args)); for (auto cq = cqs_.begin(); cq != cqs_.end(); ++cq) { grpc_server_register_completion_queue(server->server_, (*cq)->cq(), nullptr); diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index c4f799297d..56a06f4a9b 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props')" /> - <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props')" /> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> @@ -10,7 +8,7 @@ <RootNamespace>Grpc.Core</RootNamespace> <AssemblyName>Grpc.Core</AssemblyName> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> - <NuGetPackageImportStamp>8bb563fb</NuGetPackageImportStamp> + <NuGetPackageImportStamp>be3e9d03</NuGetPackageImportStamp> <DocumentationFile>bin\$(Configuration)\Grpc.Core.Xml</DocumentationFile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> @@ -147,15 +145,11 @@ <PropertyGroup> <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> </PropertyGroup> - <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props'))" /> - <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets'))" /> - <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props'))" /> - <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets'))" /> + <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets'))" /> + <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets'))" /> </Target> - <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" /> - <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" /> <ItemGroup /> - <ItemGroup> - <Folder Include="Profiling\" /> - </ItemGroup> -</Project> + <ItemGroup /> + <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" /> + <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" /> +</Project>
\ No newline at end of file diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index e9ec30e923..818ddb83b9 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -41,6 +41,6 @@ namespace Grpc.Core /// <summary> /// Current version of gRPC C# /// </summary> - public const string CurrentVersion = "0.7.1"; + public const string CurrentVersion = "0.12.0"; } } diff --git a/src/csharp/Grpc.Core/packages.config b/src/csharp/Grpc.Core/packages.config index 9b12b9b096..89600744a7 100644 --- a/src/csharp/Grpc.Core/packages.config +++ b/src/csharp/Grpc.Core/packages.config @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" /> - <package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" /> + <package id="grpc.dependencies.openssl.redist" version="1.0.204.1" targetFramework="net45" /> + <package id="grpc.dependencies.zlib.redist" version="1.2.8.10" targetFramework="net45" /> <package id="Ix-Async" version="1.2.3" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj index 8b245ade2e..342eead1a3 100644 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> @@ -57,4 +57,7 @@ <Name>Grpc.IntegrationTesting</Name> </ProjectReference> </ItemGroup> + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config b/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config new file mode 100644 index 0000000000..940d25cae3 --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration>
\ No newline at end of file diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat index b864a955a8..45f6b26c66 100644 --- a/src/csharp/build_packages.bat +++ b/src/csharp/build_packages.bat @@ -1,8 +1,8 @@ @rem Builds gRPC NuGet packages @rem Current package versions -set VERSION=0.7.1 -set CORE_VERSION=0.11.1 +set VERSION=0.12.0 +set CORE_VERSION=0.12.0 set PROTOBUF_VERSION=3.0.0-alpha4 @rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well. diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 183931936e..b8705c49d3 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -930,11 +930,12 @@ typedef void(GPR_CALLTYPE *grpcsharp_metadata_interceptor_func)( void *state, const char *service_url, grpc_credentials_plugin_metadata_cb cb, void *user_data, gpr_int32 is_destroy); -static void grpcsharp_get_metadata_handler(void *state, const char *service_url, - grpc_credentials_plugin_metadata_cb cb, void *user_data) { +static void grpcsharp_get_metadata_handler( + void *state, grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, void *user_data) { grpcsharp_metadata_interceptor_func interceptor = (grpcsharp_metadata_interceptor_func)(gpr_intptr)state; - interceptor(state, service_url, cb, user_data, 0); + interceptor(state, context.service_url, cb, user_data, 0); } static void grpcsharp_metadata_credentials_destroy_handler(void *state) { @@ -949,6 +950,7 @@ GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_metadata_credentials_cr plugin.get_metadata = grpcsharp_get_metadata_handler; plugin.destroy = grpcsharp_metadata_credentials_destroy_handler; plugin.state = (void*)(gpr_intptr)metadata_interceptor; + plugin.type = ""; return grpc_metadata_credentials_create_from_plugin(plugin, NULL); } diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc index e1786ddba7..c306292c04 100644 --- a/src/node/ext/byte_buffer.cc +++ b/src/node/ext/byte_buffer.cc @@ -77,6 +77,7 @@ Local<Value> ByteBufferToBuffer(grpc_byte_buffer *buffer) { while (grpc_byte_buffer_reader_next(&reader, &next) != 0) { memcpy(result + offset, GPR_SLICE_START_PTR(next), GPR_SLICE_LENGTH(next)); offset += GPR_SLICE_LENGTH(next); + gpr_slice_unref(next); } return scope.Escape(MakeFastBuffer( Nan::NewBuffer(result, length).ToLocalChecked())); diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index a98ae85427..1b2ab21dfe 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -234,6 +234,12 @@ class SendMetadataOp : public Op { class SendMessageOp : public Op { public: + SendMessageOp() { send_message = NULL; } + ~SendMessageOp() { + if (send_message != NULL) { + grpc_byte_buffer_destroy(send_message); + } + } Local<Value> GetNodeValue() const { EscapableHandleScope scope; return scope.Escape(Nan::True()); @@ -253,7 +259,8 @@ class SendMessageOp : public Op { out->flags = maybe_flag.FromMaybe(0) & GRPC_WRITE_USED_MASK; } } - out->data.send_message = BufferToByteBuffer(value); + send_message = BufferToByteBuffer(value); + out->data.send_message = send_message; PersistentValue *handle = new PersistentValue(value); resources->handles.push_back(unique_ptr<PersistentValue>(handle)); return true; @@ -262,6 +269,9 @@ class SendMessageOp : public Op { std::string GetTypeString() const { return "send_message"; } + + private: + grpc_byte_buffer *send_message; }; class SendClientCloseOp : public Op { diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc index 9c5d9d291b..8cbfb1ebea 100644 --- a/src/node/ext/call_credentials.cc +++ b/src/node/ext/call_credentials.cc @@ -162,6 +162,7 @@ NAN_METHOD(CallCredentials::CreateFromPlugin) { plugin.get_metadata = plugin_get_metadata; plugin.destroy = plugin_destroy_state; plugin.state = reinterpret_cast<void*>(state); + plugin.type = ""; grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin( plugin, NULL); info.GetReturnValue().Set(WrapStruct(creds)); @@ -225,7 +226,7 @@ NAUV_WORK_CB(SendPluginCallback) { uv_close((uv_handle_t *)async, (uv_close_cb)free); } -void plugin_get_metadata(void *state, const char *service_url, +void plugin_get_metadata(void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data) { uv_async_t *async = static_cast<uv_async_t*>(malloc(sizeof(uv_async_t))); @@ -234,7 +235,7 @@ void plugin_get_metadata(void *state, const char *service_url, SendPluginCallback); plugin_callback_data *data = new plugin_callback_data; data->state = reinterpret_cast<plugin_state*>(state); - data->service_url = service_url; + data->service_url = context.service_url; data->cb = cb; data->user_data = user_data; async->data = data; diff --git a/src/node/ext/call_credentials.h b/src/node/ext/call_credentials.h index 1cd8d8dd5d..a9bfe30f94 100644 --- a/src/node/ext/call_credentials.h +++ b/src/node/ext/call_credentials.h @@ -84,7 +84,7 @@ typedef struct plugin_callback_data { void *user_data; } plugin_callback_data; -void plugin_get_metadata(void *state, const char *service_url, +void plugin_get_metadata(void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data); diff --git a/src/objective-c/README.md b/src/objective-c/README.md index c1d25b96f5..30d9aad64c 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -48,8 +48,8 @@ Pod::Spec.new do |s| s.version = '0.0.1' s.license = '...' - s.ios.deployment_target = '6.0' - s.osx.deployment_target = '10.8' + s.ios.deployment_target = '7.1' + s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. # You can run this command manually if you later change your protos and need to regenerate. @@ -60,7 +60,7 @@ Pod::Spec.new do |s| ms.source_files = "*.pbobjc.{h,m}" ms.header_mappings_dir = "." ms.requires_arc = false - ms.dependency "Protobuf", "~> 3.0.0-alpha-3" + ms.dependency "Protobuf", "~> 3.0.0-alpha-4" end # The --objcgrpc_out plugin generates a pair of .pbrpc.h/.pbrpc.m files for each .proto file with @@ -69,7 +69,7 @@ Pod::Spec.new do |s| ss.source_files = "*.pbrpc.{h,m}" ss.header_mappings_dir = "." ss.requires_arc = true - ss.dependency "gRPC", "~> 0.5" + ss.dependency "gRPC", "~> 0.12" ss.dependency "#{s.name}/Messages" end end @@ -156,7 +156,7 @@ _protoc_, in which case no system modification nor renaming is necessary. You need to compile the generated `.pbobjc.*` files (the enums and messages) without ARC support, and the generated `.pbrpc.*` files (the services) with ARC support. The generated code depends on -v0.5+ of the Objective-C gRPC runtime library and v3.0.0-alpha-3+ of the Objective-C Protobuf +v0.12+ of the Objective-C gRPC runtime library and v3.0.0-alpha-4+ of the Objective-C Protobuf runtime library. These libraries need to be integrated into your project as described in their respective Podspec diff --git a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec index d4f8084cb5..5addf26fc4 100644 --- a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec @@ -3,8 +3,8 @@ Pod::Spec.new do |s| s.version = "0.0.1" s.license = "New BSD" - s.ios.deployment_target = "6.0" - s.osx.deployment_target = "10.8" + s.ios.deployment_target = '7.1' + s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. s.prepare_command = <<-CMD @@ -22,7 +22,7 @@ Pod::Spec.new do |s| ss.source_files = "*.pbrpc.{h,m}" ss.header_mappings_dir = "." ss.requires_arc = true - ss.dependency "gRPC", "~> 0.7" + ss.dependency "gRPC", "~> 0.12" ss.dependency "#{s.name}/Messages" end end diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index 8710753e59..6ecef0593b 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -3,8 +3,8 @@ Pod::Spec.new do |s| s.version = "0.0.1" s.license = "New BSD" - s.ios.deployment_target = "6.0" - s.osx.deployment_target = "10.8" + s.ios.deployment_target = '7.1' + s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. s.prepare_command = <<-CMD @@ -18,14 +18,14 @@ Pod::Spec.new do |s| ms.source_files = "*.pbobjc.{h,m}" ms.header_mappings_dir = "." ms.requires_arc = false - ms.dependency "Protobuf", "~> 3.0.0-alpha-3" + ms.dependency "Protobuf", "~> 3.0.0-alpha-4" end s.subspec "Services" do |ss| ss.source_files = "*.pbrpc.{h,m}" ss.header_mappings_dir = "." ss.requires_arc = true - ss.dependency "gRPC", "~> 0.5" + ss.dependency "gRPC", "~> 0.12" ss.dependency "#{s.name}/Messages" end end diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 598f4e7fa1..c4fc5644f2 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -51,4 +51,5 @@ xcodebuild \ -scheme AllTests \ -destination name="iPhone 6" \ test \ - | egrep "$XCODEBUILD_FILTER" - + | egrep "$XCODEBUILD_FILTER" \ + | egrep -v "(GPBDictionary|GPBArray)" - diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php index aa4de349ea..7b2627f516 100755 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -216,7 +216,7 @@ class BaseStub */ public function _simpleRequest($method, $argument, - callable $deserialize, + $deserialize, $metadata = [], $options = []) { diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 7972272e2d..db9385e961 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -94,6 +94,10 @@ else end $CFLAGS << ' -I' + File.join(grpc_root, 'include') $LDFLAGS << ' -L' + grpc_lib_dir + if grpc_config == 'gcov' + $CFLAGS << ' -O0 -fprofile-arcs -ftest-coverage' + $LDFLAGS << ' -fprofile-arcs -ftest-coverage -rdynamic' + end raise 'gpr not found' unless have_library('gpr', 'gpr_now') raise 'grpc not found' unless have_library('grpc', 'grpc_channel_destroy') end |