aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/iomgr/pollset_posix.c4
-rw-r--r--src/core/iomgr/resolve_address_posix.c15
-rw-r--r--src/core/security/auth.c17
-rw-r--r--src/core/security/credentials.c12
-rw-r--r--src/core/security/factories.c30
-rw-r--r--src/core/security/google_default_credentials.c4
-rw-r--r--src/core/security/json_token.c2
-rw-r--r--src/core/security/security_context.c5
-rw-r--r--src/core/security/server_secure_chttp2.c111
-rw-r--r--src/core/support/histogram.c35
-rw-r--r--src/core/support/slice_buffer.c7
-rw-r--r--src/core/surface/call.c21
-rw-r--r--src/core/surface/channel.c2
-rw-r--r--src/core/surface/init.c16
-rw-r--r--src/core/surface/init.h1
-rw-r--r--src/core/surface/lame_client.c2
-rw-r--r--src/core/surface/lame_client.h42
-rw-r--r--src/core/surface/secure_server_create.c57
-rw-r--r--src/core/surface/server.c4
-rw-r--r--src/core/surface/server_chttp2.c7
-rw-r--r--src/core/tsi/fake_transport_security.c4
-rw-r--r--src/core/tsi/ssl_transport_security.c5
-rw-r--r--src/core/tsi/transport_security.c2
23 files changed, 218 insertions, 187 deletions
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index f0a8453fd7..0bb722e2b1 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -66,7 +66,7 @@ static void backup_poller(void *p) {
gpr_timespec next_poll = gpr_time_add(last_poll, delta);
grpc_pollset_work(&g_backup_pollset, gpr_time_add(gpr_now(), gpr_time_from_seconds(1)));
gpr_mu_unlock(&g_backup_pollset.mu);
- /*gpr_sleep_until(next_poll);*/
+ gpr_sleep_until(next_poll);
gpr_mu_lock(&g_backup_pollset.mu);
last_poll = next_poll;
}
@@ -267,7 +267,6 @@ static void unary_poll_do_promote(void *args, int success) {
* and we don't have any mechanism to unbecome multipoller. */
pollset->in_flight_cbs--;
if (pollset->shutting_down) {
- gpr_log(GPR_INFO, "Shutting down");
/* We don't care about this pollset anymore. */
if (pollset->in_flight_cbs == 0) {
do_shutdown_cb = 1;
@@ -275,7 +274,6 @@ static void unary_poll_do_promote(void *args, int success) {
} else if (grpc_fd_is_orphaned(fd)) {
/* Don't try to add it to anything, we'll drop our ref on it below */
} else if (pollset->vtable != original_vtable) {
- gpr_log(GPR_INFO, "Not original vtable");
pollset->vtable->add_fd(pollset, fd);
} else if (fd != pollset->data.ptr) {
grpc_fd *fds[2];
diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c
index 989b968ae2..9a9283c93c 100644
--- a/src/core/iomgr/resolve_address_posix.c
+++ b/src/core/iomgr/resolve_address_posix.c
@@ -102,6 +102,21 @@ grpc_resolved_addresses *grpc_blocking_resolve_address(
s = getaddrinfo(host, port, &hints, &result);
if (s != 0) {
+ /* Retry if well-known service name is recognized */
+ char *svc[][2] = {
+ {"http", "80"},
+ {"https", "443"}
+ };
+ int i;
+ for (i = 0; i < (int)(sizeof(svc) / sizeof(svc[0])); i++) {
+ if (strcmp(port, svc[i][0]) == 0) {
+ s = getaddrinfo(host, svc[i][1], &hints, &result);
+ break;
+ }
+ }
+ }
+
+ if (s != 0) {
gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s));
goto done;
}
diff --git a/src/core/security/auth.c b/src/core/security/auth.c
index 9b67d59cb8..5fc6d2717f 100644
--- a/src/core/security/auth.c
+++ b/src/core/security/auth.c
@@ -59,6 +59,7 @@ typedef struct {
grpc_mdstr *authority_string;
grpc_mdstr *path_string;
grpc_mdstr *error_msg_key;
+ grpc_mdstr *status_key;
} channel_data;
static void do_nothing(void *ignored, grpc_op_error error) {}
@@ -66,17 +67,25 @@ static void do_nothing(void *ignored, grpc_op_error error) {}
static void bubbleup_error(grpc_call_element *elem, const char *error_msg) {
grpc_call_op finish_op;
channel_data *channeld = elem->channel_data;
+ char status[GPR_LTOA_MIN_BUFSIZE];
gpr_log(GPR_ERROR, "%s", error_msg);
finish_op.type = GRPC_RECV_METADATA;
finish_op.dir = GRPC_CALL_UP;
finish_op.flags = 0;
finish_op.data.metadata = grpc_mdelem_from_metadata_strings(
- channeld->md_ctx, channeld->error_msg_key,
+ channeld->md_ctx, grpc_mdstr_ref(channeld->error_msg_key),
grpc_mdstr_from_string(channeld->md_ctx, error_msg));
finish_op.done_cb = do_nothing;
finish_op.user_data = NULL;
grpc_call_next_op(elem, &finish_op);
+
+ gpr_ltoa(GRPC_STATUS_UNAUTHENTICATED, status);
+ finish_op.data.metadata = grpc_mdelem_from_metadata_strings(
+ channeld->md_ctx, grpc_mdstr_ref(channeld->status_key),
+ grpc_mdstr_from_string(channeld->md_ctx, status));
+ grpc_call_next_op(elem, &finish_op);
+
grpc_call_element_send_cancel(elem);
}
@@ -151,6 +160,7 @@ static void on_host_checked(void *user_data, grpc_security_status status) {
grpc_mdstr_as_c_string(calld->host));
bubbleup_error(elem, error_msg);
gpr_free(error_msg);
+ calld->op.done_cb(calld->op.user_data, GRPC_OP_ERROR);
}
}
@@ -193,6 +203,7 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
call_host);
bubbleup_error(elem, error_msg);
gpr_free(error_msg);
+ op->done_cb(op->user_data, GRPC_OP_ERROR);
}
break;
}
@@ -265,6 +276,7 @@ static void init_channel_elem(grpc_channel_element *elem,
channeld->path_string = grpc_mdstr_from_string(channeld->md_ctx, ":path");
channeld->error_msg_key =
grpc_mdstr_from_string(channeld->md_ctx, "grpc-message");
+ channeld->status_key = grpc_mdstr_from_string(channeld->md_ctx, "grpc-status");
}
/* Destructor for channel data */
@@ -279,6 +291,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
if (channeld->error_msg_key != NULL) {
grpc_mdstr_unref(channeld->error_msg_key);
}
+ if (channeld->status_key != NULL) {
+ grpc_mdstr_unref(channeld->status_key);
+ }
if (channeld->path_string != NULL) {
grpc_mdstr_unref(channeld->path_string);
}
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 7e72b238c8..3ad1e7edd7 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -348,7 +348,7 @@ static void jwt_get_request_metadata(grpc_credentials *creds,
{
gpr_mu_lock(&c->cache_mu);
if (c->cached.service_url != NULL &&
- !strcmp(c->cached.service_url, service_url) &&
+ strcmp(c->cached.service_url, service_url) == 0 &&
c->cached.jwt_md != NULL &&
(gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now()),
refresh_threshold) > 0)) {
@@ -957,7 +957,7 @@ static grpc_credentials_array get_creds_array(grpc_credentials **creds_addr) {
grpc_credentials *creds = *creds_addr;
result.creds_array = creds_addr;
result.num_creds = 1;
- if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
+ if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0) {
result = *grpc_composite_credentials_get_credentials(creds);
}
return result;
@@ -995,7 +995,7 @@ const grpc_credentials_array *grpc_composite_credentials_get_credentials(
grpc_credentials *creds) {
const grpc_composite_credentials *c =
(const grpc_composite_credentials *)creds;
- GPR_ASSERT(!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE));
+ GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
return &c->inner;
}
@@ -1003,14 +1003,14 @@ grpc_credentials *grpc_credentials_contains_type(
grpc_credentials *creds, const char *type,
grpc_credentials **composite_creds) {
size_t i;
- if (!strcmp(creds->type, type)) {
+ if (strcmp(creds->type, type) == 0) {
if (composite_creds != NULL) *composite_creds = NULL;
return creds;
- } else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
+ } else if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0) {
const grpc_credentials_array *inner_creds_array =
grpc_composite_credentials_get_credentials(creds);
for (i = 0; i < inner_creds_array->num_creds; i++) {
- if (!strcmp(type, inner_creds_array->creds_array[i]->type)) {
+ if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) {
if (composite_creds != NULL) *composite_creds = creds;
return inner_creds_array->creds_array[i];
}
diff --git a/src/core/security/factories.c b/src/core/security/factories.c
index c9701b9080..02267d5545 100644
--- a/src/core/security/factories.c
+++ b/src/core/security/factories.c
@@ -33,9 +33,9 @@
#include <string.h>
+#include <grpc/grpc.h>
#include "src/core/security/credentials.h"
#include "src/core/security/security_context.h"
-#include "src/core/surface/lame_client.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
@@ -50,31 +50,3 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
return grpc_secure_channel_create_with_factories(
factories, GPR_ARRAY_SIZE(factories), creds, target, args);
}
-
-grpc_server *grpc_secure_server_create(grpc_server_credentials *creds,
- grpc_completion_queue *cq,
- const grpc_channel_args *args) {
- grpc_security_status status = GRPC_SECURITY_ERROR;
- grpc_security_context *ctx = NULL;
- grpc_server *server = NULL;
- if (creds == NULL) return NULL; /* TODO(ctiller): Return lame server. */
-
- if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
- status = grpc_ssl_server_security_context_create(
- grpc_ssl_server_credentials_get_config(creds), &ctx);
- } else if (!strcmp(creds->type,
- GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) {
- ctx = grpc_fake_server_security_context_create();
- status = GRPC_SECURITY_OK;
- }
-
- if (status != GRPC_SECURITY_OK) {
- gpr_log(GPR_ERROR,
- "Unable to create secure server with credentials of type %s.",
- creds->type);
- return NULL; /* TODO(ctiller): Return lame server. */
- }
- server = grpc_secure_server_create_internal(cq, args, ctx);
- grpc_security_context_unref(ctx);
- return server;
-}
diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c
index dc0e453b87..bdc907e7b3 100644
--- a/src/core/security/google_default_credentials.c
+++ b/src/core/security/google_default_credentials.c
@@ -75,8 +75,8 @@ static void on_compute_engine_detection_http_response(
size_t i;
for (i = 0; i < response->hdr_count; i++) {
grpc_httpcli_header *header = &response->hdrs[i];
- if (!strcmp(header->key, "Metadata-Flavor") &&
- !strcmp(header->value, "Google")) {
+ if (strcmp(header->key, "Metadata-Flavor") == 0 &&
+ strcmp(header->value, "Google") == 0) {
detector->success = 1;
break;
}
diff --git a/src/core/security/json_token.c b/src/core/security/json_token.c
index 26d57036a6..40b612b206 100644
--- a/src/core/security/json_token.c
+++ b/src/core/security/json_token.c
@@ -257,7 +257,7 @@ static char *dot_concat_and_free_strings(char *str1, char *str2) {
}
const EVP_MD *openssl_digest_from_algorithm(const char *algorithm) {
- if (!strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM)) {
+ if (strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM) == 0) {
return EVP_sha256();
} else {
gpr_log(GPR_ERROR, "Unknown algorithm %s.", algorithm);
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index 0dc37fa73c..e180cad52b 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -42,7 +42,6 @@
#include "src/core/support/env.h"
#include "src/core/support/file.h"
#include "src/core/support/string.h"
-#include "src/core/surface/lame_client.h"
#include "src/core/transport/chttp2/alpn.h"
#include <grpc/support/alloc.h>
@@ -422,7 +421,7 @@ static grpc_security_status ssl_channel_check_call_host(
/* If the target name was overridden, then the original target_name was
'checked' transitively during the previous peer check at the end of the
handshake. */
- if (c->overridden_target_name != NULL && !strcmp(host, c->target_name)) {
+ if (c->overridden_target_name != NULL && strcmp(host, c->target_name) == 0) {
return GRPC_SECURITY_OK;
} else {
return GRPC_SECURITY_ERROR;
@@ -611,7 +610,7 @@ grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
for (i = 0; args && i < args->num_args; i++) {
grpc_arg *arg = &args->args[i];
- if (!strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) &&
+ if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
arg->type == GRPC_ARG_STRING) {
overridden_target_name = arg->value.string;
break;
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index c88f0726bb..c155b80b7e 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -33,8 +33,11 @@
#include <grpc/grpc.h>
+#include <string.h>
+
#include "src/core/channel/http_filter.h"
#include "src/core/channel/http_server_filter.h"
+#include "src/core/iomgr/endpoint.h"
#include "src/core/iomgr/resolve_address.h"
#include "src/core/iomgr/tcp_server.h"
#include "src/core/security/security_context.h"
@@ -43,8 +46,29 @@
#include "src/core/transport/chttp2_transport.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
#include <grpc/support/useful.h>
+typedef struct grpc_server_secure_state {
+ grpc_server *server;
+ grpc_tcp_server *tcp;
+ grpc_security_context *ctx;
+ int is_shutdown;
+ gpr_mu mu;
+ gpr_refcount refcount;
+} grpc_server_secure_state;
+
+static void state_ref(grpc_server_secure_state *state) {
+ gpr_ref(&state->refcount);
+}
+
+static void state_unref(grpc_server_secure_state *state) {
+ if (gpr_unref(&state->refcount)) {
+ grpc_security_context_unref(state->ctx);
+ gpr_free(state);
+ }
+}
+
static grpc_transport_setup_result setup_transport(void *server,
grpc_transport *transport,
grpc_mdctx *mdctx) {
@@ -54,49 +78,84 @@ static grpc_transport_setup_result setup_transport(void *server,
GPR_ARRAY_SIZE(extra_filters), mdctx);
}
-static void on_secure_transport_setup_done(void *server,
+static void on_secure_transport_setup_done(void *statep,
grpc_security_status status,
grpc_endpoint *secure_endpoint) {
+ grpc_server_secure_state *state = statep;
if (status == GRPC_SECURITY_OK) {
- grpc_create_chttp2_transport(
- setup_transport, server, grpc_server_get_channel_args(server),
- secure_endpoint, NULL, 0, grpc_mdctx_create(), 0);
+ gpr_mu_lock(&state->mu);
+ if (!state->is_shutdown) {
+ grpc_create_chttp2_transport(
+ setup_transport, state->server,
+ grpc_server_get_channel_args(state->server),
+ secure_endpoint, NULL, 0, grpc_mdctx_create(), 0);
+ } else {
+ /* We need to consume this here, because the server may already have gone
+ * away. */
+ grpc_endpoint_destroy(secure_endpoint);
+ }
+ gpr_mu_unlock(&state->mu);
} else {
gpr_log(GPR_ERROR, "Secure transport failed with error %d", status);
}
+ state_unref(state);
}
-static void on_accept(void *server, grpc_endpoint *tcp) {
- const grpc_channel_args *args = grpc_server_get_channel_args(server);
- grpc_security_context *ctx = grpc_find_security_context_in_args(args);
- GPR_ASSERT(ctx);
- grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, server);
+static void on_accept(void *statep, grpc_endpoint *tcp) {
+ grpc_server_secure_state *state = statep;
+ state_ref(state);
+ grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done, state);
}
-/* Note: the following code is the same with server_chttp2.c */
-
/* Server callback: start listening on our ports */
-static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets,
+static void start(grpc_server *server, void *statep, grpc_pollset **pollsets,
size_t pollset_count) {
- grpc_tcp_server *tcp = tcpp;
- grpc_tcp_server_start(tcp, pollsets, pollset_count, on_accept, server);
+ grpc_server_secure_state *state = statep;
+ grpc_tcp_server_start(state->tcp, pollsets, pollset_count, on_accept, state);
}
/* Server callback: destroy the tcp listener (so we don't generate further
callbacks) */
-static void destroy(grpc_server *server, void *tcpp) {
- grpc_tcp_server *tcp = tcpp;
- grpc_tcp_server_destroy(tcp);
+static void destroy(grpc_server *server, void *statep) {
+ grpc_server_secure_state *state = statep;
+ gpr_mu_lock(&state->mu);
+ state->is_shutdown = 1;
+ grpc_tcp_server_destroy(state->tcp);
+ gpr_mu_unlock(&state->mu);
+ state_unref(state);
}
-int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
+int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) {
grpc_resolved_addresses *resolved = NULL;
grpc_tcp_server *tcp = NULL;
+ grpc_server_secure_state *state = NULL;
size_t i;
unsigned count = 0;
int port_num = -1;
int port_temp;
+ grpc_security_status status = GRPC_SECURITY_ERROR;
+ grpc_security_context *ctx = NULL;
+ /* create security context */
+ if (creds == NULL) goto error;
+
+ if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL) == 0) {
+ status = grpc_ssl_server_security_context_create(
+ grpc_ssl_server_credentials_get_config(creds), &ctx);
+ } else if (strcmp(creds->type,
+ GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) == 0) {
+ ctx = grpc_fake_server_security_context_create();
+ status = GRPC_SECURITY_OK;
+ }
+
+ if (status != GRPC_SECURITY_OK) {
+ gpr_log(GPR_ERROR,
+ "Unable to create secure server with credentials of type %s.",
+ creds->type);
+ goto error;
+ }
+
+ /* resolve address */
resolved = grpc_blocking_resolve_address(addr, "https");
if (!resolved) {
goto error;
@@ -132,18 +191,32 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
}
grpc_resolved_addresses_destroy(resolved);
+ state = gpr_malloc(sizeof(*state));
+ state->server = server;
+ state->tcp = tcp;
+ state->ctx = ctx;
+ state->is_shutdown = 0;
+ gpr_mu_init(&state->mu);
+ gpr_ref_init(&state->refcount, 1);
+
/* Register with the server only upon success */
- grpc_server_add_listener(server, tcp, start, destroy);
+ grpc_server_add_listener(server, state, start, destroy);
return port_num;
/* Error path: cleanup and return */
error:
+ if (ctx) {
+ grpc_security_context_unref(ctx);
+ }
if (resolved) {
grpc_resolved_addresses_destroy(resolved);
}
if (tcp) {
grpc_tcp_server_destroy(tcp);
}
+ if (state) {
+ gpr_free(state);
+ }
return 0;
}
diff --git a/src/core/support/histogram.c b/src/core/support/histogram.c
index eacb77082f..ed344b43e8 100644
--- a/src/core/support/histogram.c
+++ b/src/core/support/histogram.c
@@ -126,25 +126,35 @@ void gpr_histogram_add(gpr_histogram *h, double x) {
}
int gpr_histogram_merge(gpr_histogram *dst, gpr_histogram *src) {
- size_t i;
if ((dst->num_buckets != src->num_buckets) ||
(dst->multiplier != src->multiplier)) {
/* Fail because these histograms don't match */
return 0;
}
- dst->sum += src->sum;
- dst->sum_of_squares += src->sum_of_squares;
- dst->count += src->count;
- if (src->min_seen < dst->min_seen) {
- dst->min_seen = src->min_seen;
+ gpr_histogram_merge_contents(dst, src->buckets, src->num_buckets,
+ src->min_seen, src->max_seen, src->sum,
+ src->sum_of_squares, src->count);
+ return 1;
+}
+
+void gpr_histogram_merge_contents(gpr_histogram *dst, const gpr_uint32 *data,
+ size_t data_count, double min_seen,
+ double max_seen, double sum,
+ double sum_of_squares, double count) {
+ size_t i;
+ GPR_ASSERT(dst->num_buckets == data_count);
+ dst->sum += sum;
+ dst->sum_of_squares += sum_of_squares;
+ dst->count += count;
+ if (min_seen < dst->min_seen) {
+ dst->min_seen = min_seen;
}
- if (src->max_seen > dst->max_seen) {
- dst->max_seen = src->max_seen;
+ if (max_seen > dst->max_seen) {
+ dst->max_seen = max_seen;
}
for (i = 0; i < dst->num_buckets; i++) {
- dst->buckets[i] += src->buckets[i];
+ dst->buckets[i] += data[i];
}
- return 1;
}
static double threshold_for_count_below(gpr_histogram *h, double count_below) {
@@ -222,3 +232,8 @@ double gpr_histogram_sum(gpr_histogram *h) { return h->sum; }
double gpr_histogram_sum_of_squares(gpr_histogram *h) {
return h->sum_of_squares;
}
+
+const gpr_uint32 *gpr_histogram_get_contents(gpr_histogram *h, size_t *size) {
+ *size = h->num_buckets;
+ return h->buckets;
+}
diff --git a/src/core/support/slice_buffer.c b/src/core/support/slice_buffer.c
index 6cd51f925c..b280e4bd02 100644
--- a/src/core/support/slice_buffer.c
+++ b/src/core/support/slice_buffer.c
@@ -143,6 +143,13 @@ void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *s, size_t n) {
}
}
+void gpr_slice_buffer_pop(gpr_slice_buffer *sb) {
+ if (sb->count != 0) {
+ size_t count = --sb->count;
+ sb->length -= GPR_SLICE_LENGTH(sb->slices[count]);
+ }
+}
+
void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb) {
size_t i;
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 7cf3c0e4fd..cfce943794 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -140,6 +140,8 @@ struct grpc_call {
gpr_uint8 have_alarm;
/* are we currently performing a send operation */
gpr_uint8 sending;
+ /* are we currently completing requests */
+ gpr_uint8 completing;
/* pairs with completed_requests */
gpr_uint8 num_completed_requests;
/* flag that we need to request more data */
@@ -357,7 +359,7 @@ static void lock(grpc_call *call) { gpr_mu_lock(&call->mu); }
static void unlock(grpc_call *call) {
send_action sa = SEND_NOTHING;
completed_request completed_requests[GRPC_IOREQ_OP_COUNT];
- int num_completed_requests = call->num_completed_requests;
+ int completing_requests = 0;
int need_more_data =
call->need_more_data &&
(call->write_state >= WRITE_STATE_STARTED || !call->is_client);
@@ -367,10 +369,13 @@ static void unlock(grpc_call *call) {
call->need_more_data = 0;
}
- if (num_completed_requests != 0) {
+ if (!call->completing && call->num_completed_requests != 0) {
+ completing_requests = call->num_completed_requests;
memcpy(completed_requests, call->completed_requests,
sizeof(completed_requests));
call->num_completed_requests = 0;
+ call->completing = 1;
+ grpc_call_internal_ref(call);
}
if (!call->sending) {
@@ -391,9 +396,15 @@ static void unlock(grpc_call *call) {
enact_send_action(call, sa);
}
- for (i = 0; i < num_completed_requests; i++) {
- completed_requests[i].on_complete(call, completed_requests[i].status,
- completed_requests[i].user_data);
+ if (completing_requests > 0) {
+ for (i = 0; i < completing_requests; i++) {
+ completed_requests[i].on_complete(call, completed_requests[i].status,
+ completed_requests[i].user_data);
+ }
+ lock(call);
+ call->completing = 0;
+ unlock(call);
+ grpc_call_internal_unref(call, 0);
}
}
diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
index e38734c6a4..e764a3b9af 100644
--- a/src/core/surface/channel.c
+++ b/src/core/surface/channel.c
@@ -39,6 +39,7 @@
#include "src/core/iomgr/iomgr.h"
#include "src/core/surface/call.h"
#include "src/core/surface/client.h"
+#include "src/core/surface/init.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@@ -63,6 +64,7 @@ grpc_channel *grpc_channel_create_from_filters(
size_t size =
sizeof(grpc_channel) + grpc_channel_stack_size(filters, num_filters);
grpc_channel *channel = gpr_malloc(size);
+ GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
channel->is_client = is_client;
/* decremented by grpc_channel_destroy, and grpc_client_channel_closed if is_client */
gpr_ref_init(&channel->refs, 1 + is_client);
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
index 4db66fb66e..e48c4202e5 100644
--- a/src/core/surface/init.c
+++ b/src/core/surface/init.c
@@ -40,17 +40,17 @@
#include "src/core/surface/surface_trace.h"
#include "src/core/transport/chttp2_transport.h"
-static gpr_once g_init = GPR_ONCE_INIT;
+static gpr_once g_basic_init = GPR_ONCE_INIT;
static gpr_mu g_init_mu;
static int g_initializations;
-static void do_init(void) {
+static void do_basic_init(void) {
gpr_mu_init(&g_init_mu);
g_initializations = 0;
}
void grpc_init(void) {
- gpr_once_init(&g_init, do_init);
+ gpr_once_init(&g_basic_init, do_basic_init);
gpr_mu_lock(&g_init_mu);
if (++g_initializations == 1) {
@@ -73,3 +73,13 @@ void grpc_shutdown(void) {
}
gpr_mu_unlock(&g_init_mu);
}
+
+int grpc_is_initialized(void) {
+ int r;
+ gpr_once_init(&g_basic_init, do_basic_init);
+ gpr_mu_lock(&g_init_mu);
+ r = g_initializations > 0;
+ gpr_mu_unlock(&g_init_mu);
+ return r;
+}
+
diff --git a/src/core/surface/init.h b/src/core/surface/init.h
index ab40bedf87..416874020d 100644
--- a/src/core/surface/init.h
+++ b/src/core/surface/init.h
@@ -35,5 +35,6 @@
#define GRPC_INTERNAL_CORE_SURFACE_INIT_H
void grpc_security_pre_init(void);
+int grpc_is_initialized(void);
#endif /* GRPC_INTERNAL_CORE_SURFACE_INIT_H */
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
index 57f6ddf0f7..b40c48381f 100644
--- a/src/core/surface/lame_client.c
+++ b/src/core/surface/lame_client.c
@@ -31,7 +31,7 @@
*
*/
-#include "src/core/surface/lame_client.h"
+#include <grpc/grpc.h>
#include <string.h>
diff --git a/src/core/surface/lame_client.h b/src/core/surface/lame_client.h
deleted file mode 100644
index b13e8cb6ef..0000000000
--- a/src/core/surface/lame_client.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#ifndef GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H
-#define GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H
-
-#include <grpc/grpc.h>
-
-/* Create a lame client: this client fails every operation attempted on it. */
-grpc_channel *grpc_lame_client_channel_create(void);
-
-#endif /* GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H */
diff --git a/src/core/surface/secure_server_create.c b/src/core/surface/secure_server_create.c
deleted file mode 100644
index 1d5b927997..0000000000
--- a/src/core/surface/secure_server_create.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#include <grpc/grpc.h>
-
-#include "src/core/channel/channel_args.h"
-#include "src/core/security/security_context.h"
-#include "src/core/surface/completion_queue.h"
-#include "src/core/surface/server.h"
-#include <grpc/support/log.h>
-
-grpc_server *grpc_secure_server_create_internal(
- grpc_completion_queue *cq, const grpc_channel_args *args,
- grpc_security_context *context) {
- grpc_arg context_arg;
- grpc_channel_args *args_copy;
- grpc_server *server;
- if (grpc_find_security_context_in_args(args) != NULL) {
- gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
- }
-
- context_arg = grpc_security_context_to_arg(context);
- args_copy = grpc_channel_args_copy_and_add(args, &context_arg);
- server = grpc_server_create_from_filters(cq, NULL, 0, args_copy);
- grpc_channel_args_destroy(args_copy);
- return server;
-}
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index c99a1b4cc9..424734c54c 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -44,6 +44,7 @@
#include "src/core/surface/call.h"
#include "src/core/surface/channel.h"
#include "src/core/surface/completion_queue.h"
+#include "src/core/surface/init.h"
#include "src/core/transport/metadata.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@@ -612,6 +613,9 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
int census_enabled = grpc_channel_args_is_census_enabled(args);
grpc_server *server = gpr_malloc(sizeof(grpc_server));
+
+ GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
+
memset(server, 0, sizeof(grpc_server));
if (cq) addcq(server, cq);
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
index fd702593b8..27434b39e2 100644
--- a/src/core/surface/server_chttp2.c
+++ b/src/core/surface/server_chttp2.c
@@ -53,6 +53,13 @@ static grpc_transport_setup_result setup_transport(void *server,
}
static void new_transport(void *server, grpc_endpoint *tcp) {
+ /*
+ * Beware that the call to grpc_create_chttp2_transport() has to happen before
+ * grpc_tcp_server_destroy(). This is fine here, but similar code
+ * asynchronously doing a handshake instead of calling grpc_tcp_server_start()
+ * (as in server_secure_chttp2.c) needs to add synchronization to avoid this
+ * case.
+ */
grpc_create_chttp2_transport(setup_transport, server,
grpc_server_get_channel_args(server), tcp, NULL,
0, grpc_mdctx_create(), 0);
diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c
index f58f04ea20..9ce1ddb95e 100644
--- a/src/core/tsi/fake_transport_security.c
+++ b/src/core/tsi/fake_transport_security.c
@@ -102,8 +102,8 @@ static tsi_result tsi_fake_handshake_message_from_string(
const char* msg_string, tsi_fake_handshake_message* msg) {
int i;
for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) {
- if (!strncmp(msg_string, tsi_fake_handshake_message_strings[i],
- strlen(tsi_fake_handshake_message_strings[i]))) {
+ if (strncmp(msg_string, tsi_fake_handshake_message_strings[i],
+ strlen(tsi_fake_handshake_message_strings[i])) == 0) {
*msg = i;
return TSI_OK;
}
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index dc43f7e270..33645ca8b8 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -1083,7 +1083,8 @@ static int does_entry_match_name(const char* entry, size_t entry_length,
if (entry_length == 0) return 0;
}
- if ((name_length == entry_length) && !strncmp(name, entry, entry_length)) {
+ if ((name_length == entry_length) &&
+ strncmp(name, entry, entry_length) == 0) {
return 1; /* Perfect match. */
}
if (entry[0] != '*') return 0;
@@ -1110,7 +1111,7 @@ static int does_entry_match_name(const char* entry, size_t entry_length,
name_subdomain_length--;
}
return ((entry_length > 0) && (name_subdomain_length == entry_length) &&
- !strncmp(entry, name_subdomain, entry_length));
+ strncmp(entry, name_subdomain, entry_length) == 0);
}
static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap,
diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c
index c8c74c5de5..f4ab9d2bc6 100644
--- a/src/core/tsi/transport_security.c
+++ b/src/core/tsi/transport_security.c
@@ -208,7 +208,7 @@ const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* self,
return property;
}
if (name != NULL && property->name != NULL &&
- !strcmp(property->name, name)) {
+ strcmp(property->name, name) == 0) {
return property;
}
}