aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2015-01-13 16:11:30 -0800
committerGravatar Craig Tiller <ctiller@google.com>2015-01-13 16:11:30 -0800
commit375605b65f9d58b7544b4af8bc93d4cf8489f010 (patch)
treebc0e1a8861a3dfdb6e8b0bb43a219d31efb88064 /src/core
parent80fa15c15121a7d0ec020dec8bfa3697a96058b6 (diff)
parent49a06a6cb843b8ce592312c28b43c9dc527b99ee (diff)
Merge github.com:google/grpc into api
Diffstat (limited to 'src/core')
-rw-r--r--src/core/channel/channel_args.h2
-rw-r--r--src/core/channel/channel_stack.c11
-rw-r--r--src/core/channel/channel_stack.h2
-rw-r--r--src/core/channel/client_channel.h2
-rw-r--r--src/core/channel/client_setup.h2
-rw-r--r--src/core/channel/connected_channel.c49
-rw-r--r--src/core/channel/connected_channel.h2
-rw-r--r--src/core/channel/http_server_filter.c108
-rw-r--r--src/core/channel/metadata_buffer.c2
-rw-r--r--src/core/channel/metadata_buffer.h2
-rw-r--r--src/core/channel/noop_filter.c4
-rw-r--r--src/core/channel/noop_filter.h2
-rw-r--r--src/core/compression/algorithm.h2
-rw-r--r--src/core/compression/message_compress.h2
-rw-r--r--src/core/httpcli/format_request.h2
-rw-r--r--src/core/httpcli/httpcli.h2
-rw-r--r--src/core/httpcli/httpcli_security_context.h2
-rw-r--r--src/core/httpcli/parser.h2
-rw-r--r--src/core/iomgr/pollset.h1
-rw-r--r--src/core/iomgr/sockaddr_utils.c28
-rw-r--r--src/core/iomgr/sockaddr_utils.h6
-rw-r--r--src/core/iomgr/tcp_server.h5
-rw-r--r--src/core/iomgr/tcp_server_posix.c87
-rw-r--r--src/core/security/auth.c5
-rw-r--r--src/core/security/auth.h2
-rw-r--r--src/core/security/credentials.c21
-rw-r--r--src/core/security/credentials.h12
-rw-r--r--src/core/security/factories.c80
-rw-r--r--src/core/security/google_root_certs.h2
-rw-r--r--src/core/security/secure_endpoint.h2
-rw-r--r--src/core/security/secure_transport_setup.h2
-rw-r--r--src/core/security/security_context.c131
-rw-r--r--src/core/security/security_context.h36
-rw-r--r--src/core/security/server_secure_chttp2.c3
-rw-r--r--src/core/statistics/census_interface.h2
-rw-r--r--src/core/statistics/census_rpc_stats.h2
-rw-r--r--src/core/statistics/census_tracing.c30
-rw-r--r--src/core/statistics/hash_table.c6
-rw-r--r--src/core/support/alloc.c4
-rw-r--r--src/core/support/cpu.h2
-rw-r--r--src/core/support/cpu_linux.c24
-rw-r--r--src/core/support/log.c23
-rw-r--r--src/core/support/log_android.c24
-rw-r--r--src/core/support/log_linux.c31
-rw-r--r--src/core/support/log_posix.c41
-rw-r--r--src/core/support/log_win32.c40
-rw-r--r--src/core/support/murmur_hash.h2
-rw-r--r--src/core/support/thd_internal.h2
-rw-r--r--src/core/surface/call.c2
-rw-r--r--src/core/surface/call.h2
-rw-r--r--src/core/surface/channel.c2
-rw-r--r--src/core/surface/channel.h2
-rw-r--r--src/core/surface/client.c7
-rw-r--r--src/core/surface/client.h2
-rw-r--r--src/core/surface/completion_queue.h2
-rw-r--r--src/core/surface/event_string.h2
-rw-r--r--src/core/surface/lame_client.c29
-rw-r--r--src/core/surface/server.c4
-rw-r--r--src/core/surface/server.h2
-rw-r--r--src/core/surface/server_chttp2.c16
-rw-r--r--src/core/surface/surface_trace.h2
-rw-r--r--src/core/transport/chttp2/frame.h2
-rw-r--r--src/core/transport/chttp2/frame_data.c1
-rw-r--r--src/core/transport/chttp2/frame_data.h2
-rw-r--r--src/core/transport/chttp2/frame_ping.h2
-rw-r--r--src/core/transport/chttp2/frame_rst_stream.h2
-rw-r--r--src/core/transport/chttp2/frame_settings.h2
-rw-r--r--src/core/transport/chttp2/frame_window_update.h2
-rw-r--r--src/core/transport/chttp2/hpack_parser.h2
-rw-r--r--src/core/transport/chttp2/hpack_table.c124
-rw-r--r--src/core/transport/chttp2/hpack_table.h2
-rw-r--r--src/core/transport/chttp2/http2_errors.h2
-rw-r--r--src/core/transport/chttp2/status_conversion.h2
-rw-r--r--src/core/transport/chttp2/stream_encoder.c130
-rw-r--r--src/core/transport/chttp2/stream_encoder.h17
-rw-r--r--src/core/transport/chttp2/stream_map.h2
-rw-r--r--src/core/transport/chttp2/varint.h2
-rw-r--r--src/core/transport/chttp2_transport.c246
-rw-r--r--src/core/transport/chttp2_transport.h2
-rw-r--r--src/core/transport/metadata.h2
-rw-r--r--src/core/transport/stream_op.h2
-rw-r--r--src/core/transport/transport.h2
-rw-r--r--src/core/transport/transport_impl.h2
-rw-r--r--src/core/tsi/fake_transport_security.c24
-rw-r--r--src/core/tsi/fake_transport_security.h3
-rw-r--r--src/core/tsi/fake_transport_security_test.cc151
-rw-r--r--src/core/tsi/ssl_transport_security.c78
-rw-r--r--src/core/tsi/ssl_transport_security.h14
-rw-r--r--src/core/tsi/ssl_transport_security_test.cc534
-rw-r--r--src/core/tsi/transport_security.c35
-rw-r--r--src/core/tsi/transport_security.h4
-rw-r--r--src/core/tsi/transport_security_interface.h48
-rw-r--r--src/core/tsi/transport_security_test_lib.cc363
-rw-r--r--src/core/tsi/transport_security_test_lib.h154
94 files changed, 1048 insertions, 1842 deletions
diff --git a/src/core/channel/channel_args.h b/src/core/channel/channel_args.h
index cf38d5d01f..92280450a1 100644
--- a/src/core/channel/channel_args.h
+++ b/src/core/channel/channel_args.h
@@ -51,4 +51,4 @@ void grpc_channel_args_destroy(grpc_channel_args *a);
is specified in channel args, otherwise returns 0. */
int grpc_channel_args_is_census_enabled(const grpc_channel_args *a);
-#endif /* __GRPC_INTERNAL_CHANNEL_CHANNEL_ARGS_H__ */
+#endif /* __GRPC_INTERNAL_CHANNEL_CHANNEL_ARGS_H__ */
diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c
index 5ee412bf7d..14fc800778 100644
--- a/src/core/channel/channel_stack.c
+++ b/src/core/channel/channel_stack.c
@@ -54,7 +54,7 @@
/* Given a size, round up to the next multiple of sizeof(void*) */
#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
- (((x)+GPR_MAX_ALIGNMENT - 1) & ~(GPR_MAX_ALIGNMENT - 1))
+ (((x) + GPR_MAX_ALIGNMENT - 1) & ~(GPR_MAX_ALIGNMENT - 1))
size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
size_t filter_count) {
@@ -190,14 +190,13 @@ void grpc_channel_next_op(grpc_channel_element *elem, grpc_channel_op *op) {
grpc_channel_stack *grpc_channel_stack_from_top_element(
grpc_channel_element *elem) {
- return (grpc_channel_stack *)((char *)(elem) -
- ROUND_UP_TO_ALIGNMENT_SIZE(
- sizeof(grpc_channel_stack)));
+ return (grpc_channel_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE(
+ sizeof(grpc_channel_stack)));
}
grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) {
- return (grpc_call_stack *)((char *)(elem) - ROUND_UP_TO_ALIGNMENT_SIZE(
- sizeof(grpc_call_stack)));
+ return (grpc_call_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE(
+ sizeof(grpc_call_stack)));
}
static void do_nothing(void *user_data, grpc_op_error error) {}
diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h
index 14e972f539..eb68102b43 100644
--- a/src/core/channel/channel_stack.h
+++ b/src/core/channel/channel_stack.h
@@ -302,4 +302,4 @@ void grpc_call_element_send_cancel(grpc_call_element *cur_elem);
} while (0)
#endif
-#endif /* __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__ */
+#endif /* __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__ */
diff --git a/src/core/channel/client_channel.h b/src/core/channel/client_channel.h
index 576af64ec7..6b8a7d95a8 100644
--- a/src/core/channel/client_channel.h
+++ b/src/core/channel/client_channel.h
@@ -59,4 +59,4 @@ grpc_transport_setup_result grpc_client_channel_transport_setup_complete(
grpc_channel_filter const **channel_filters, size_t num_channel_filters,
grpc_mdctx *mdctx);
-#endif /* __GRPC_INTERNAL_CHANNEL_CLIENT_CHANNEL_H__ */
+#endif /* __GRPC_INTERNAL_CHANNEL_CLIENT_CHANNEL_H__ */
diff --git a/src/core/channel/client_setup.h b/src/core/channel/client_setup.h
index a508785e60..155a9a5b1a 100644
--- a/src/core/channel/client_setup.h
+++ b/src/core/channel/client_setup.h
@@ -64,4 +64,4 @@ gpr_timespec grpc_client_setup_request_deadline(grpc_client_setup_request *r);
grpc_mdctx *grpc_client_setup_get_mdctx(grpc_client_setup_request *r);
-#endif /* __GRPC_INTERNAL_CHANNEL_CLIENT_SETUP_H__ */
+#endif /* __GRPC_INTERNAL_CHANNEL_CLIENT_SETUP_H__ */
diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c
index 5faa03c2f4..30de10905c 100644
--- a/src/core/channel/connected_channel.c
+++ b/src/core/channel/connected_channel.c
@@ -69,7 +69,7 @@ typedef struct {
/* We perform a small hack to locate transport data alongside the connected
channel data in call allocations, to allow everything to be pulled in minimal
cache line requests */
-#define TRANSPORT_STREAM_FROM_CALL_DATA(calld) ((grpc_stream *)((calld)+1))
+#define TRANSPORT_STREAM_FROM_CALL_DATA(calld) ((grpc_stream *)((calld) + 1))
#define CALL_DATA_FROM_TRANSPORT_STREAM(transport_stream) \
(((call_data *)(transport_stream)) - 1)
@@ -257,9 +257,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_connected_channel_filter = {
- call_op, channel_op,
+ call_op, channel_op,
- sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
@@ -289,12 +289,8 @@ static void accept_stream(void *user_data, grpc_transport *transport,
}
static void recv_error(channel_data *chand, call_data *calld, int line,
- const char *fmt, ...) {
- va_list a;
-
- va_start(a, fmt);
- gpr_vlog(__FILE__, line, GPR_LOG_SEVERITY_ERROR, fmt, a);
- va_end(a);
+ const char *message) {
+ gpr_log_message(__FILE__, line, GPR_LOG_SEVERITY_ERROR, message);
if (chand->transport) {
grpc_transport_abort_stream(chand->transport,
@@ -388,19 +384,23 @@ static void recv_batch(void *user_data, grpc_transport *transport,
case GRPC_OP_BEGIN_MESSAGE:
/* can't begin a message when we're still reading a message */
if (calld->reading_message) {
- recv_error(chand, calld, __LINE__,
- "Message terminated early; read %d bytes, expected %d",
- calld->incoming_message.length,
- calld->incoming_message_length);
+ char message[128];
+ sprintf(message,
+ "Message terminated early; read %d bytes, expected %d",
+ (int)calld->incoming_message.length,
+ (int)calld->incoming_message_length);
+ recv_error(chand, calld, __LINE__, message);
return;
}
/* stash away parameters, and prepare for incoming slices */
length = stream_op->data.begin_message.length;
if (length > calld->max_message_length) {
- recv_error(
- chand, calld, __LINE__,
+ char message[128];
+ sprintf(
+ message,
"Maximum message length of %d exceeded by a message of length %d",
calld->max_message_length, length);
+ recv_error(chand, calld, __LINE__, message);
} else if (length > 0) {
calld->reading_message = 1;
calld->incoming_message_length = length;
@@ -423,10 +423,12 @@ static void recv_batch(void *user_data, grpc_transport *transport,
gpr_slice_buffer_add(&calld->incoming_message, stream_op->data.slice);
if (calld->incoming_message.length > calld->incoming_message_length) {
/* if we got too many bytes, complain */
- recv_error(chand, calld, __LINE__,
- "Receiving message overflow; read %d bytes, expected %d",
- calld->incoming_message.length,
- calld->incoming_message_length);
+ char message[128];
+ sprintf(message,
+ "Receiving message overflow; read %d bytes, expected %d",
+ (int)calld->incoming_message.length,
+ (int)calld->incoming_message_length);
+ recv_error(chand, calld, __LINE__, message);
return;
} else if (calld->incoming_message.length ==
calld->incoming_message_length) {
@@ -439,10 +441,11 @@ static void recv_batch(void *user_data, grpc_transport *transport,
final_state == GRPC_STREAM_CLOSED)) {
calld->got_read_close = 1;
if (calld->reading_message) {
- recv_error(chand, calld, __LINE__,
- "Last message truncated; read %d bytes, expected %d",
- calld->incoming_message.length,
- calld->incoming_message_length);
+ char message[128];
+ sprintf(message, "Last message truncated; read %d bytes, expected %d",
+ (int)calld->incoming_message.length,
+ (int)calld->incoming_message_length);
+ recv_error(chand, calld, __LINE__, message);
}
call_op.type = GRPC_RECV_HALF_CLOSE;
call_op.dir = GRPC_CALL_UP;
diff --git a/src/core/channel/connected_channel.h b/src/core/channel/connected_channel.h
index 660ea7ad89..9d143fc135 100644
--- a/src/core/channel/connected_channel.h
+++ b/src/core/channel/connected_channel.h
@@ -46,4 +46,4 @@ extern const grpc_channel_filter grpc_connected_channel_filter;
grpc_transport_setup_result grpc_connected_channel_bind_transport(
grpc_channel_stack *channel_stack, grpc_transport *transport);
-#endif /* __GRPC_INTERNAL_CHANNEL_CONNECTED_CHANNEL_H__ */
+#endif /* __GRPC_INTERNAL_CHANNEL_CONNECTED_CHANNEL_H__ */
diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c
index 9a20d79c61..44eab43f09 100644
--- a/src/core/channel/http_server_filter.c
+++ b/src/core/channel/http_server_filter.c
@@ -32,13 +32,26 @@
*/
#include "src/core/channel/http_server_filter.h"
+
+#include <string.h>
#include <grpc/support/log.h>
-typedef struct call_data { int sent_status; } call_data;
+typedef struct call_data {
+ int sent_status;
+ int seen_scheme;
+ int seen_method;
+ int seen_te_trailers;
+} call_data;
typedef struct channel_data {
grpc_mdelem *te_trailers;
- grpc_mdelem *status_md;
+ grpc_mdelem *method;
+ grpc_mdelem *http_scheme;
+ grpc_mdelem *https_scheme;
+ /* TODO(klempner): Remove this once we stop using it */
+ grpc_mdelem *grpc_scheme;
+ grpc_mdelem *content_type;
+ grpc_mdelem *status;
} channel_data;
/* used to silence 'variable not used' warnings */
@@ -56,20 +69,54 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
channel_data *channeld = elem->channel_data;
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
- ignore_unused(calld);
- ignore_unused(channeld);
-
switch (op->type) {
case GRPC_RECV_METADATA:
- /* check if it's a te: trailers header */
- if (op->data.metadata == channeld->te_trailers) {
+ /* Check if it is one of the headers we care about. */
+ if (op->data.metadata == channeld->te_trailers ||
+ op->data.metadata == channeld->method ||
+ op->data.metadata == channeld->http_scheme ||
+ op->data.metadata == channeld->https_scheme ||
+ op->data.metadata == channeld->grpc_scheme ||
+ op->data.metadata == channeld->content_type) {
/* swallow it */
+ if (op->data.metadata == channeld->method) {
+ calld->seen_method = 1;
+ } else if (op->data.metadata->key == channeld->http_scheme->key) {
+ calld->seen_scheme = 1;
+ } else if (op->data.metadata == channeld->te_trailers) {
+ calld->seen_te_trailers = 1;
+ }
+ /* TODO(klempner): Track that we've seen all the headers we should
+ require */
grpc_mdelem_unref(op->data.metadata);
op->done_cb(op->user_data, GRPC_OP_OK);
- } else if (op->data.metadata->key == channeld->te_trailers->key) {
- gpr_log(GPR_ERROR, "Invalid te: header: '%s'",
+ } else if (op->data.metadata->key == channeld->content_type->key) {
+ if (strncmp(grpc_mdstr_as_c_string(op->data.metadata->value),
+ "application/grpc+", 17) == 0) {
+ /* Although the C implementation doesn't (currently) generate them,
+ any
+ custom +-suffix is explicitly valid. */
+ /* TODO(klempner): We should consider preallocating common values such
+ as +proto or +json, or at least stashing them if we see them. */
+ /* TODO(klempner): Should we be surfacing this to application code? */
+ } else {
+ /* TODO(klempner): We're currently allowing this, but we shouldn't
+ see it without a proxy so log for now. */
+ gpr_log(GPR_INFO, "Unexpected content-type %s",
+ channeld->content_type->key);
+ }
+ grpc_mdelem_unref(op->data.metadata);
+ op->done_cb(op->user_data, GRPC_OP_OK);
+ } else if (op->data.metadata->key == channeld->te_trailers->key ||
+ op->data.metadata->key == channeld->method->key ||
+ op->data.metadata->key == channeld->http_scheme->key ||
+ op->data.metadata->key == channeld->content_type->key) {
+ gpr_log(GPR_ERROR, "Invalid %s: header: '%s'",
+ grpc_mdstr_as_c_string(op->data.metadata->key),
grpc_mdstr_as_c_string(op->data.metadata->value));
- /* swallow it */
+ /* swallow it and error everything out. */
+ /* TODO(klempner): We ought to generate more descriptive error messages
+ on the wire here. */
grpc_mdelem_unref(op->data.metadata);
op->done_cb(op->user_data, GRPC_OP_OK);
grpc_call_element_send_cancel(elem);
@@ -78,14 +125,33 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
grpc_call_next_op(elem, op);
}
break;
+ case GRPC_RECV_END_OF_INITIAL_METADATA:
+ /* Have we seen the required http2 transport headers?
+ (:method, :scheme, content-type, with :path and :authority covered
+ at the channel level right now) */
+ if (calld->seen_method && calld->seen_scheme && calld->seen_te_trailers) {
+ grpc_call_next_op(elem, op);
+ } else {
+ if (!calld->seen_method) {
+ gpr_log(GPR_ERROR, "Missing :method header");
+ } else if (!calld->seen_scheme) {
+ gpr_log(GPR_ERROR, "Missing :scheme header");
+ } else if (!calld->seen_te_trailers) {
+ gpr_log(GPR_ERROR, "Missing te trailers header");
+ }
+ /* Error this call out */
+ op->done_cb(op->user_data, GRPC_OP_OK);
+ grpc_call_element_send_cancel(elem);
+ }
+ break;
case GRPC_SEND_START:
case GRPC_SEND_METADATA:
/* If we haven't sent status 200 yet, we need to so so because it needs to
come before any non : prefixed metadata. */
if (!calld->sent_status) {
calld->sent_status = 1;
- /* status_md is reffed by grpc_call_element_send_metadata */
- grpc_call_element_send_metadata(elem, channeld->status_md);
+ /* status is reffed by grpc_call_element_send_metadata */
+ grpc_call_element_send_metadata(elem, channeld->status);
}
grpc_call_next_op(elem, op);
break;
@@ -124,6 +190,9 @@ static void init_call_elem(grpc_call_element *elem,
/* initialize members */
calld->sent_status = 0;
+ calld->seen_scheme = 0;
+ calld->seen_method = 0;
+ calld->seen_te_trailers = 0;
}
/* Destructor for call_data */
@@ -151,7 +220,13 @@ static void init_channel_elem(grpc_channel_element *elem,
/* initialize members */
channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers");
- channeld->status_md = grpc_mdelem_from_strings(mdctx, ":status", "200");
+ channeld->status = grpc_mdelem_from_strings(mdctx, ":status", "200");
+ channeld->method = grpc_mdelem_from_strings(mdctx, ":method", "POST");
+ channeld->http_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "http");
+ channeld->https_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "https");
+ channeld->grpc_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "grpc");
+ channeld->content_type =
+ grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc");
}
/* Destructor for channel data */
@@ -160,7 +235,12 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
channel_data *channeld = elem->channel_data;
grpc_mdelem_unref(channeld->te_trailers);
- grpc_mdelem_unref(channeld->status_md);
+ grpc_mdelem_unref(channeld->status);
+ grpc_mdelem_unref(channeld->method);
+ grpc_mdelem_unref(channeld->http_scheme);
+ grpc_mdelem_unref(channeld->https_scheme);
+ grpc_mdelem_unref(channeld->grpc_scheme);
+ grpc_mdelem_unref(channeld->content_type);
}
const grpc_channel_filter grpc_http_server_filter = {
diff --git a/src/core/channel/metadata_buffer.c b/src/core/channel/metadata_buffer.c
index 75fd90b707..d4de4ba576 100644
--- a/src/core/channel/metadata_buffer.c
+++ b/src/core/channel/metadata_buffer.c
@@ -61,7 +61,7 @@ struct grpc_metadata_buffer_impl {
size_t elem_cap;
};
-#define ELEMS(buffer) ((qelem *)((buffer)+1))
+#define ELEMS(buffer) ((qelem *)((buffer) + 1))
void grpc_metadata_buffer_init(grpc_metadata_buffer *buffer) {
/* start buffer as NULL, indicating no elements */
diff --git a/src/core/channel/metadata_buffer.h b/src/core/channel/metadata_buffer.h
index 818b290ce2..011dabed1b 100644
--- a/src/core/channel/metadata_buffer.h
+++ b/src/core/channel/metadata_buffer.h
@@ -67,4 +67,4 @@ grpc_metadata *grpc_metadata_buffer_extract_elements(
grpc_metadata_buffer *buffer);
void grpc_metadata_buffer_cleanup_elements(void *elements, grpc_op_error error);
-#endif /* __GRPC_INTERNAL_CHANNEL_METADATA_BUFFER_H__ */
+#endif /* __GRPC_INTERNAL_CHANNEL_METADATA_BUFFER_H__ */
diff --git a/src/core/channel/noop_filter.c b/src/core/channel/noop_filter.c
index b6b3f661f7..6f854a2b87 100644
--- a/src/core/channel/noop_filter.c
+++ b/src/core/channel/noop_filter.c
@@ -131,9 +131,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_no_op_filter = {
- call_op, channel_op,
+ call_op, channel_op,
- sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
diff --git a/src/core/channel/noop_filter.h b/src/core/channel/noop_filter.h
index 4057ff7ac9..269214f893 100644
--- a/src/core/channel/noop_filter.h
+++ b/src/core/channel/noop_filter.h
@@ -41,4 +41,4 @@
customize for their own filters */
extern const grpc_channel_filter grpc_no_op_filter;
-#endif /* __GRPC_INTERNAL_CHANNEL_NOOP_FILTER_H__ */
+#endif /* __GRPC_INTERNAL_CHANNEL_NOOP_FILTER_H__ */
diff --git a/src/core/compression/algorithm.h b/src/core/compression/algorithm.h
index 05895a889e..c5ec6d21b6 100644
--- a/src/core/compression/algorithm.h
+++ b/src/core/compression/algorithm.h
@@ -46,4 +46,4 @@ typedef enum {
const char *grpc_compression_algorithm_name(
grpc_compression_algorithm algorithm);
-#endif /* __GRPC_INTERNAL_COMPRESSION_ALGORITHM_H__ */
+#endif /* __GRPC_INTERNAL_COMPRESSION_ALGORITHM_H__ */
diff --git a/src/core/compression/message_compress.h b/src/core/compression/message_compress.h
index af8a0a5d75..564ca69a87 100644
--- a/src/core/compression/message_compress.h
+++ b/src/core/compression/message_compress.h
@@ -49,4 +49,4 @@ int grpc_msg_compress(grpc_compression_algorithm algorithm,
int grpc_msg_decompress(grpc_compression_algorithm algorithm,
gpr_slice_buffer *input, gpr_slice_buffer *output);
-#endif /* __GRPC_INTERNAL_COMPRESSION_MESSAGE_COMPRESS_H__ */
+#endif /* __GRPC_INTERNAL_COMPRESSION_MESSAGE_COMPRESS_H__ */
diff --git a/src/core/httpcli/format_request.h b/src/core/httpcli/format_request.h
index 988f872563..a82130cb93 100644
--- a/src/core/httpcli/format_request.h
+++ b/src/core/httpcli/format_request.h
@@ -42,4 +42,4 @@ gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request,
const char *body_bytes,
size_t body_size);
-#endif /* __GRPC_INTERNAL_HTTPCLI_FORMAT_REQUEST_H__ */
+#endif /* __GRPC_INTERNAL_HTTPCLI_FORMAT_REQUEST_H__ */
diff --git a/src/core/httpcli/httpcli.h b/src/core/httpcli/httpcli.h
index ef8031354c..90f89a9366 100644
--- a/src/core/httpcli/httpcli.h
+++ b/src/core/httpcli/httpcli.h
@@ -115,4 +115,4 @@ typedef int (*grpc_httpcli_post_override)(const grpc_httpcli_request *request,
void grpc_httpcli_set_override(grpc_httpcli_get_override get,
grpc_httpcli_post_override post);
-#endif /* __GRPC_INTERNAL_HTTPCLI_HTTPCLI_H__ */
+#endif /* __GRPC_INTERNAL_HTTPCLI_HTTPCLI_H__ */
diff --git a/src/core/httpcli/httpcli_security_context.h b/src/core/httpcli/httpcli_security_context.h
index c267622e60..a73ecca0b3 100644
--- a/src/core/httpcli/httpcli_security_context.h
+++ b/src/core/httpcli/httpcli_security_context.h
@@ -40,4 +40,4 @@ grpc_security_status grpc_httpcli_ssl_channel_security_context_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size,
const char *secure_peer_name, grpc_channel_security_context **ctx);
-#endif /* __GRPC_INTERNAL_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H__ */
+#endif /* __GRPC_INTERNAL_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H__ */
diff --git a/src/core/httpcli/parser.h b/src/core/httpcli/parser.h
index e2c24a9993..520b16fd02 100644
--- a/src/core/httpcli/parser.h
+++ b/src/core/httpcli/parser.h
@@ -61,4 +61,4 @@ void grpc_httpcli_parser_destroy(grpc_httpcli_parser *parser);
int grpc_httpcli_parser_parse(grpc_httpcli_parser *parser, gpr_slice slice);
int grpc_httpcli_parser_eof(grpc_httpcli_parser *parser);
-#endif /* __GRPC_INTERNAL_HTTPCLI_PARSER_H__ */
+#endif /* __GRPC_INTERNAL_HTTPCLI_PARSER_H__ */
diff --git a/src/core/iomgr/pollset.h b/src/core/iomgr/pollset.h
index 7374a4ec13..36d80d5c29 100644
--- a/src/core/iomgr/pollset.h
+++ b/src/core/iomgr/pollset.h
@@ -35,6 +35,7 @@
#define __GRPC_INTERNAL_IOMGR_POLLSET_H_
#include <grpc/support/port_platform.h>
+#include <grpc/support/time.h>
/* A grpc_pollset is a set of file descriptors that a higher level item is
interested in. For example:
diff --git a/src/core/iomgr/sockaddr_utils.c b/src/core/iomgr/sockaddr_utils.c
index f709d35162..eca14a4f39 100644
--- a/src/core/iomgr/sockaddr_utils.c
+++ b/src/core/iomgr/sockaddr_utils.c
@@ -153,3 +153,31 @@ int grpc_sockaddr_to_string(char **out, const struct sockaddr *addr,
errno = save_errno;
return ret;
}
+
+int grpc_sockaddr_get_port(const struct sockaddr *addr) {
+ switch (addr->sa_family) {
+ case AF_INET:
+ return ntohs(((struct sockaddr_in *)addr)->sin_port);
+ case AF_INET6:
+ return ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
+ default:
+ gpr_log(GPR_ERROR, "Unknown socket family %d in %s", addr->sa_family,
+ __FUNCTION__);
+ return 0;
+ }
+}
+
+int grpc_sockaddr_set_port(const struct sockaddr *addr, int port) {
+ switch (addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)addr)->sin_port = htons(port);
+ return 1;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
+ return 1;
+ default:
+ gpr_log(GPR_ERROR, "Unknown socket family %d in %s", addr->sa_family,
+ __FUNCTION__);
+ return 0;
+ }
+}
diff --git a/src/core/iomgr/sockaddr_utils.h b/src/core/iomgr/sockaddr_utils.h
index 753d0c824a..3f5b770e86 100644
--- a/src/core/iomgr/sockaddr_utils.h
+++ b/src/core/iomgr/sockaddr_utils.h
@@ -57,6 +57,12 @@ int grpc_sockaddr_is_wildcard(const struct sockaddr *addr, int *port_out);
void grpc_sockaddr_make_wildcards(int port, struct sockaddr_in *wild4_out,
struct sockaddr_in6 *wild6_out);
+/* Return the IP port number of a sockaddr */
+int grpc_sockaddr_get_port(const struct sockaddr *addr);
+
+/* Set IP port number of a sockaddr */
+int grpc_sockaddr_set_port(const struct sockaddr *addr, int port);
+
/* Converts a sockaddr into a newly-allocated human-readable string.
Currently, only the AF_INET and AF_INET6 families are recognized.
diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h
index 1968246b75..d881e146b9 100644
--- a/src/core/iomgr/tcp_server.h
+++ b/src/core/iomgr/tcp_server.h
@@ -52,7 +52,8 @@ grpc_tcp_server *grpc_tcp_server_create();
void grpc_tcp_server_start(grpc_tcp_server *server, grpc_pollset *pollset,
grpc_tcp_server_cb cb, void *cb_arg);
-/* Add a port to the server, returning true on success, or false otherwise.
+/* Add a port to the server, returning port number on success, or negative
+ on failure.
The :: and 0.0.0.0 wildcard addresses are treated identically, accepting
both IPv4 and IPv6 connections, but :: is the preferred style. This usually
@@ -60,6 +61,8 @@ void grpc_tcp_server_start(grpc_tcp_server *server, grpc_pollset *pollset,
but not dualstack sockets.
For raw access to the underlying sockets, see grpc_tcp_server_get_fd(). */
+/* TODO(ctiller): deprecate this, and make grpc_tcp_server_add_ports to handle
+ all of the multiple socket port matching logic in one place */
int grpc_tcp_server_add_port(grpc_tcp_server *s, const struct sockaddr *addr,
int addr_len);
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 5ed517748a..753e24c38e 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -154,6 +154,9 @@ static int get_max_accept_queue_size() {
/* Prepare a recently-created socket for listening. */
static int prepare_socket(int fd, const struct sockaddr *addr, int addr_len) {
+ struct sockaddr_storage sockname_temp;
+ socklen_t sockname_len;
+
if (fd < 0) {
goto error;
}
@@ -179,13 +182,18 @@ static int prepare_socket(int fd, const struct sockaddr *addr, int addr_len) {
goto error;
}
- return 1;
+ sockname_len = sizeof(sockname_temp);
+ if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) {
+ goto error;
+ }
+
+ return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
error:
if (fd >= 0) {
close(fd);
}
- return 0;
+ return -1;
}
/* event manager callback when reads are ready */
@@ -234,39 +242,64 @@ error:
static int add_socket_to_server(grpc_tcp_server *s, int fd,
const struct sockaddr *addr, int addr_len) {
server_port *sp;
+ int port;
- if (!prepare_socket(fd, addr, addr_len)) {
- return 0;
- }
-
- gpr_mu_lock(&s->mu);
- GPR_ASSERT(!s->cb && "must add ports before starting server");
- /* append it to the list under a lock */
- if (s->nports == s->port_capacity) {
- s->port_capacity *= 2;
- s->ports = gpr_realloc(s->ports, sizeof(server_port *) * s->port_capacity);
+ port = prepare_socket(fd, addr, addr_len);
+ if (port >= 0) {
+ gpr_mu_lock(&s->mu);
+ GPR_ASSERT(!s->cb && "must add ports before starting server");
+ /* append it to the list under a lock */
+ if (s->nports == s->port_capacity) {
+ s->port_capacity *= 2;
+ s->ports =
+ gpr_realloc(s->ports, sizeof(server_port *) * s->port_capacity);
+ }
+ sp = &s->ports[s->nports++];
+ sp->server = s;
+ sp->fd = fd;
+ sp->emfd = grpc_fd_create(fd);
+ GPR_ASSERT(sp->emfd);
+ gpr_mu_unlock(&s->mu);
}
- sp = &s->ports[s->nports++];
- sp->server = s;
- sp->fd = fd;
- sp->emfd = grpc_fd_create(fd);
- GPR_ASSERT(sp->emfd);
- gpr_mu_unlock(&s->mu);
- return 1;
+ return port;
}
int grpc_tcp_server_add_port(grpc_tcp_server *s, const struct sockaddr *addr,
int addr_len) {
- int ok = 0;
+ int allocated_port1 = -1;
+ int allocated_port2 = -1;
+ int i;
int fd;
grpc_dualstack_mode dsmode;
struct sockaddr_in6 addr6_v4mapped;
struct sockaddr_in wild4;
struct sockaddr_in6 wild6;
struct sockaddr_in addr4_copy;
+ struct sockaddr *allocated_addr = NULL;
+ struct sockaddr_storage sockname_temp;
+ socklen_t sockname_len;
int port;
+ /* Check if this is a wildcard port, and if so, try to keep the port the same
+ as some previously created listener. */
+ if (grpc_sockaddr_get_port(addr) == 0) {
+ for (i = 0; i < s->nports; i++) {
+ sockname_len = sizeof(sockname_temp);
+ if (0 == getsockname(s->ports[i].fd, (struct sockaddr *)&sockname_temp,
+ &sockname_len)) {
+ port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
+ if (port > 0) {
+ allocated_addr = malloc(addr_len);
+ memcpy(allocated_addr, addr, addr_len);
+ grpc_sockaddr_set_port(allocated_addr, port);
+ addr = allocated_addr;
+ break;
+ }
+ }
+ }
+ }
+
if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
addr = (const struct sockaddr *)&addr6_v4mapped;
addr_len = sizeof(addr6_v4mapped);
@@ -280,12 +313,15 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const struct sockaddr *addr,
addr = (struct sockaddr *)&wild6;
addr_len = sizeof(wild6);
fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
- ok |= add_socket_to_server(s, fd, addr, addr_len);
+ allocated_port1 = add_socket_to_server(s, fd, addr, addr_len);
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
- return ok;
+ goto done;
}
/* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
+ if (port == 0 && allocated_port1 > 0) {
+ grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port1);
+ }
addr = (struct sockaddr *)&wild4;
addr_len = sizeof(wild4);
}
@@ -299,8 +335,11 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const struct sockaddr *addr,
addr = (struct sockaddr *)&addr4_copy;
addr_len = sizeof(addr4_copy);
}
- ok |= add_socket_to_server(s, fd, addr, addr_len);
- return ok;
+ allocated_port2 = add_socket_to_server(s, fd, addr, addr_len);
+
+done:
+ gpr_free(allocated_addr);
+ return allocated_port1 >= 0 ? allocated_port1 : allocated_port2;
}
int grpc_tcp_server_get_fd(grpc_tcp_server *s, int index) {
diff --git a/src/core/security/auth.c b/src/core/security/auth.c
index f743b25838..e36bf2382f 100644
--- a/src/core/security/auth.c
+++ b/src/core/security/auth.c
@@ -157,6 +157,5 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_client_auth_filter = {
- call_op, channel_op, sizeof(call_data),
- init_call_elem, destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "auth"};
+ call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem, "auth"};
diff --git a/src/core/security/auth.h b/src/core/security/auth.h
index 0b279f8740..94fa2aba7d 100644
--- a/src/core/security/auth.h
+++ b/src/core/security/auth.h
@@ -38,4 +38,4 @@
extern const grpc_channel_filter grpc_client_auth_filter;
-#endif /* __GRPC_INTERNAL_SECURITY_AUTH_H__ */
+#endif /* __GRPC_INTERNAL_SECURITY_AUTH_H__ */
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index c99ac8021d..d3bba0fb1f 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -819,6 +819,26 @@ const grpc_credentials_array *grpc_composite_credentials_get_credentials(
return &c->inner;
}
+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 (composite_creds != NULL) *composite_creds = NULL;
+ return creds;
+ } else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
+ 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 (composite_creds != NULL) *composite_creds = creds;
+ return inner_creds_array->creds_array[i];
+ }
+ }
+ }
+ return NULL;
+}
+
/* -- IAM credentials. -- */
typedef struct {
@@ -877,4 +897,3 @@ grpc_credentials *grpc_iam_credentials_create(const char *token,
/* -- Default credentials TODO(jboeuf). -- */
grpc_credentials *grpc_default_credentials_create(void) { return NULL; }
-
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 036a44493e..4a2532d7c4 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -108,6 +108,14 @@ typedef struct {
const grpc_credentials_array *grpc_composite_credentials_get_credentials(
grpc_credentials *composite_creds);
+/* Returns creds if creds is of the specified type or the inner creds of the
+ specified type (if found), if the creds is of type COMPOSITE.
+ If composite_creds is not NULL, *composite_creds will point to creds if of
+ type COMPOSITE in case of success. */
+grpc_credentials *grpc_credentials_contains_type(
+ grpc_credentials *creds, const char *type,
+ grpc_credentials **composite_creds);
+
/* Exposed for testing only. */
grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
@@ -118,7 +126,6 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
grpc_credentials *grpc_fake_oauth2_credentials_create(
const char *token_md_value, int is_async);
-
/* --- grpc_server_credentials. --- */
typedef struct {
@@ -136,5 +143,4 @@ struct grpc_server_credentials {
const grpc_ssl_config *grpc_ssl_server_credentials_get_config(
const grpc_server_credentials *ssl_creds);
-
-#endif /* __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__ */
+#endif /* __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__ */
diff --git a/src/core/security/factories.c b/src/core/security/factories.c
new file mode 100644
index 0000000000..d89c692989
--- /dev/null
+++ b/src/core/security/factories.c
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2014, 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 <string.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>
+
+grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
+ const char *target,
+ const grpc_channel_args *args) {
+ grpc_secure_channel_factory factories[] = {
+ {GRPC_CREDENTIALS_TYPE_SSL, grpc_ssl_channel_create},
+ {GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY,
+ grpc_fake_transport_security_channel_create}};
+ 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_root_certs.h b/src/core/security/google_root_certs.h
index 4bcfaddcdb..30ed16c03b 100644
--- a/src/core/security/google_root_certs.h
+++ b/src/core/security/google_root_certs.h
@@ -37,4 +37,4 @@
extern unsigned char grpc_google_root_certs[];
extern unsigned int grpc_google_root_certs_size;
-#endif /* __GRPC_INTERNAL_SECURITY_GOOGLE_ROOT_CERTS_H__ */
+#endif /* __GRPC_INTERNAL_SECURITY_GOOGLE_ROOT_CERTS_H__ */
diff --git a/src/core/security/secure_endpoint.h b/src/core/security/secure_endpoint.h
index d0f0fa7d5b..20143150e0 100644
--- a/src/core/security/secure_endpoint.h
+++ b/src/core/security/secure_endpoint.h
@@ -44,4 +44,4 @@ grpc_endpoint *grpc_secure_endpoint_create(
struct tsi_frame_protector *protector, grpc_endpoint *to_wrap,
gpr_slice *leftover_slices, size_t leftover_nslices);
-#endif /* __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__ */
+#endif /* __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__ */
diff --git a/src/core/security/secure_transport_setup.h b/src/core/security/secure_transport_setup.h
index 50f2b08529..b13d065fbf 100644
--- a/src/core/security/secure_transport_setup.h
+++ b/src/core/security/secure_transport_setup.h
@@ -50,4 +50,4 @@ void grpc_setup_secure_transport(grpc_security_context *ctx,
grpc_secure_transport_setup_done_cb cb,
void *user_data);
-#endif /* __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__ */
+#endif /* __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__ */
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index 13b9a847ee..d519ecab87 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -100,8 +100,7 @@ grpc_arg grpc_security_context_to_arg(grpc_security_context *ctx) {
return result;
}
-grpc_security_context *grpc_security_context_from_arg(
- const grpc_arg *arg) {
+grpc_security_context *grpc_security_context_from_arg(const grpc_arg *arg) {
if (strcmp(arg->key, GRPC_SECURITY_CONTEXT_ARG)) return NULL;
if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
@@ -140,9 +139,7 @@ static void fake_channel_destroy(grpc_security_context *ctx) {
gpr_free(ctx);
}
-static void fake_server_destroy(grpc_security_context *ctx) {
- gpr_free(ctx);
-}
+static void fake_server_destroy(grpc_security_context *ctx) { gpr_free(ctx); }
static grpc_security_status fake_channel_create_handshaker(
grpc_security_context *ctx, tsi_handshaker **handshaker) {
@@ -234,8 +231,7 @@ static void ssl_channel_destroy(grpc_security_context *ctx) {
}
static void ssl_server_destroy(grpc_security_context *ctx) {
- grpc_ssl_server_security_context *c =
- (grpc_ssl_server_security_context *)ctx;
+ grpc_ssl_server_security_context *c = (grpc_ssl_server_security_context *)ctx;
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
@@ -267,8 +263,7 @@ static grpc_security_status ssl_channel_create_handshaker(
static grpc_security_status ssl_server_create_handshaker(
grpc_security_context *ctx, tsi_handshaker **handshaker) {
- grpc_ssl_server_security_context *c =
- (grpc_ssl_server_security_context *)ctx;
+ grpc_ssl_server_security_context *c = (grpc_ssl_server_security_context *)ctx;
return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker);
}
@@ -438,20 +433,19 @@ error:
return GRPC_SECURITY_ERROR;
}
-
-
/* -- High level objects. -- */
-static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
- const grpc_ssl_config *config,
- const char *target,
- const grpc_channel_args *args) {
+grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
+ grpc_credentials *request_metadata_creds,
+ const char *target,
+ const grpc_channel_args *args) {
grpc_channel_security_context *ctx = NULL;
grpc_channel *channel = NULL;
grpc_security_status status = GRPC_SECURITY_OK;
size_t i = 0;
const char *secure_peer_name = target;
- for (i = 0; i < args->num_args; i++) {
+
+ 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) &&
arg->type == GRPC_ARG_STRING) {
@@ -459,8 +453,9 @@ static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
break;
}
}
- status = grpc_ssl_channel_security_context_create(creds, config,
- secure_peer_name, &ctx);
+ status = grpc_ssl_channel_security_context_create(
+ request_metadata_creds, grpc_ssl_credentials_get_config(ssl_creds),
+ secure_peer_name, &ctx);
if (status != GRPC_SECURITY_OK) {
return grpc_lame_client_channel_create();
}
@@ -469,58 +464,47 @@ static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
return channel;
}
-
-static grpc_credentials *get_creds_from_composite(
- grpc_credentials *composite_creds, const char *type) {
- size_t i;
- const grpc_credentials_array *inner_creds_array =
- grpc_composite_credentials_get_credentials(composite_creds);
- for (i = 0; i < inner_creds_array->num_creds; i++) {
- if (!strcmp(type, inner_creds_array->creds_array[i]->type)) {
- return inner_creds_array->creds_array[i];
- }
- }
- return NULL;
+grpc_channel *grpc_fake_transport_security_channel_create(
+ grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds,
+ const char *target, const grpc_channel_args *args) {
+ grpc_channel_security_context *ctx =
+ grpc_fake_channel_security_context_create(request_metadata_creds);
+ grpc_channel *channel =
+ grpc_secure_channel_create_internal(target, args, ctx);
+ grpc_security_context_unref(&ctx->base);
+ return channel;
}
-static grpc_channel *grpc_channel_create_from_composite_creds(
- grpc_credentials *composite_creds, const char *target,
+grpc_channel *grpc_secure_channel_create_with_factories(
+ const grpc_secure_channel_factory *factories, size_t num_factories,
+ grpc_credentials *creds, const char *target,
const grpc_channel_args *args) {
- grpc_credentials *creds =
- get_creds_from_composite(composite_creds, GRPC_CREDENTIALS_TYPE_SSL);
- if (creds != NULL) {
- return grpc_ssl_channel_create(
- composite_creds, grpc_ssl_credentials_get_config(creds), target, args);
+ size_t i;
+ if (creds == NULL) {
+ gpr_log(GPR_ERROR, "No credentials to create a secure channel.");
+ return grpc_lame_client_channel_create();
}
- return NULL; /* TODO(ctiller): return lame channel. */
-}
-
-grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
- const char *target,
- const grpc_channel_args *args) {
if (grpc_credentials_has_request_metadata_only(creds)) {
gpr_log(GPR_ERROR,
"Credentials is insufficient to create a secure channel.");
return grpc_lame_client_channel_create();
}
- if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
- return grpc_ssl_channel_create(NULL, grpc_ssl_credentials_get_config(creds),
- target, args);
- } else if (!strcmp(creds->type,
- GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) {
- grpc_channel_security_context *ctx =
- grpc_fake_channel_security_context_create(NULL);
- grpc_channel *channel =
- grpc_secure_channel_create_internal(target, args, ctx);
- grpc_security_context_unref(&ctx->base);
- return channel;
- } else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
- return grpc_channel_create_from_composite_creds(creds, target, args);
- } else {
- gpr_log(GPR_ERROR,
- "Unknown credentials type %s for creating a secure channel.");
- return grpc_lame_client_channel_create();
+
+ for (i = 0; i < num_factories; i++) {
+ grpc_credentials *composite_creds = NULL;
+ grpc_credentials *transport_security_creds = NULL;
+ transport_security_creds = grpc_credentials_contains_type(
+ creds, factories[i].creds_type, &composite_creds);
+ if (transport_security_creds != NULL) {
+ return factories[i].factory(transport_security_creds, composite_creds,
+ target, args);
+ }
}
+
+ gpr_log(GPR_ERROR,
+ "Unknown credentials type %s for creating a secure channel.",
+ creds->type);
+ return grpc_lame_client_channel_create();
}
grpc_channel *grpc_default_secure_channel_create(
@@ -528,30 +512,3 @@ grpc_channel *grpc_default_secure_channel_create(
return grpc_secure_channel_create(grpc_default_credentials_create(), 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;
- } else {
- gpr_log(GPR_ERROR,
- "Unable to create secure server with credentials of type %s.",
- creds->type);
- }
- if (status != GRPC_SECURITY_OK) {
- 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/security_context.h b/src/core/security/security_context.h
index bbd7ff3b1a..9ace7f1ccb 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -118,7 +118,7 @@ grpc_security_context *grpc_find_security_context_in_args(
typedef struct grpc_channel_security_context grpc_channel_security_context;
struct grpc_channel_security_context {
- grpc_security_context base; /* requires is_client_side to be non 0. */
+ grpc_security_context base; /* requires is_client_side to be non 0. */
grpc_credentials *request_metadata_creds;
};
@@ -159,17 +159,41 @@ grpc_security_status grpc_ssl_channel_security_context_create(
grpc_security_status grpc_ssl_server_security_context_create(
const grpc_ssl_config *config, grpc_security_context **ctx);
-
/* --- Creation of high level objects. --- */
/* Secure client channel creation. */
+
+grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
+ grpc_credentials *request_metadata_creds,
+ const char *target,
+ const grpc_channel_args *args);
+
+grpc_channel *grpc_fake_transport_security_channel_create(
+ grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds,
+ const char *target, const grpc_channel_args *args);
+
grpc_channel *grpc_secure_channel_create_internal(
const char *target, const grpc_channel_args *args,
grpc_channel_security_context *ctx);
+typedef grpc_channel *(*grpc_secure_channel_factory_func)(
+ grpc_credentials *transport_security_creds,
+ grpc_credentials *request_metadata_creds, const char *target,
+ const grpc_channel_args *args);
+
+typedef struct {
+ const char *creds_type;
+ grpc_secure_channel_factory_func factory;
+} grpc_secure_channel_factory;
+
+grpc_channel *grpc_secure_channel_create_with_factories(
+ const grpc_secure_channel_factory *factories, size_t num_factories,
+ grpc_credentials *creds, const char *target, const grpc_channel_args *args);
+
/* Secure server creation. */
-grpc_server *grpc_secure_server_create_internal(
- grpc_completion_queue *cq, const grpc_channel_args *args,
- grpc_security_context *ctx);
-#endif /* __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__ */
+grpc_server *grpc_secure_server_create_internal(grpc_completion_queue *cq,
+ const grpc_channel_args *args,
+ grpc_security_context *ctx);
+
+#endif /* __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__ */
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 9d7c0e5e5a..931fa95651 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -70,8 +70,7 @@ 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);
+ grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, server);
}
/* Note: the following code is the same with server_chttp2.c */
diff --git a/src/core/statistics/census_interface.h b/src/core/statistics/census_interface.h
index 7618387ee2..af9c70c4fb 100644
--- a/src/core/statistics/census_interface.h
+++ b/src/core/statistics/census_interface.h
@@ -73,4 +73,4 @@ census_op_id census_tracing_start_op();
/* Ends tracing. Calling this function will invalidate the input op_id. */
void census_tracing_end_op(census_op_id op_id);
-#endif /* __GRPC_INTERNAL_STATISTICS_CENSUS_INTERFACE_H__ */
+#endif /* __GRPC_INTERNAL_STATISTICS_CENSUS_INTERFACE_H__ */
diff --git a/src/core/statistics/census_rpc_stats.h b/src/core/statistics/census_rpc_stats.h
index e1ff3ac31b..a9c999aa5c 100644
--- a/src/core/statistics/census_rpc_stats.h
+++ b/src/core/statistics/census_rpc_stats.h
@@ -98,4 +98,4 @@ void census_stats_store_shutdown();
}
#endif
-#endif /* __GRPC_INTERNAL_STATISTICS_CENSUS_RPC_STATS_H__ */
+#endif /* __GRPC_INTERNAL_STATISTICS_CENSUS_RPC_STATS_H__ */
diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c
index d37c427c5b..45302cd6ab 100644
--- a/src/core/statistics/census_tracing.c
+++ b/src/core/statistics/census_tracing.c
@@ -47,8 +47,8 @@
/* Struct for a trace annotation. */
typedef struct annotation {
- gpr_uint64 ts; /* timestamp of the annotation */
- char txt[CENSUS_MAX_ANNOTATION_LENGTH]; /* actual txt annotation */
+ gpr_timespec ts; /* timestamp of the annotation */
+ char txt[CENSUS_MAX_ANNOTATION_LENGTH + 1]; /* actual txt annotation */
struct annotation* next;
} annotation;
@@ -107,8 +107,8 @@ census_op_id census_tracing_start_op() {
ret->rpc_stats.cnt = 1;
ret->ts = gpr_now();
census_ht_insert(g_trace_store, op_id_as_key(&ret->id), (void*)ret);
+ gpr_log(GPR_DEBUG, "Start tracing for id %lu", g_id);
gpr_mu_unlock(&g_mu);
- gpr_log(GPR_DEBUG, "Start tracing for id %lu\n", g_id);
return ret->id;
}
}
@@ -127,7 +127,27 @@ int census_add_method_tag(census_op_id op_id, const char* method) {
return ret;
}
-void census_tracing_print(census_op_id op_id, const char* annotation) {}
+void census_tracing_print(census_op_id op_id, const char* anno_txt) {
+ trace_obj* trace = NULL;
+ gpr_mu_lock(&g_mu);
+ trace = census_ht_find(g_trace_store, op_id_as_key(&op_id));
+ if (trace != NULL) {
+ annotation* anno = gpr_malloc(sizeof(annotation));
+ anno->ts = gpr_now();
+ {
+ char* d = anno->txt;
+ const char* s = anno_txt;
+ int n = 0;
+ for (; n < CENSUS_MAX_ANNOTATION_LENGTH && *s != '\0'; ++n) {
+ *d++ = *s++;
+ }
+ *d = '\0';
+ }
+ anno->next = trace->annotations;
+ trace->annotations = anno;
+ }
+ gpr_mu_unlock(&g_mu);
+}
void census_tracing_end_op(census_op_id op_id) {
trace_obj* trace = NULL;
@@ -136,7 +156,7 @@ void census_tracing_end_op(census_op_id op_id) {
if (trace != NULL) {
trace->rpc_stats.elapsed_time_ms =
gpr_timespec_to_micros(gpr_time_sub(gpr_now(), trace->ts));
- gpr_log(GPR_DEBUG, "End tracing for id %lu, method %s, latency %f us\n",
+ gpr_log(GPR_DEBUG, "End tracing for id %lu, method %s, latency %f us",
op_id_2_uint64(&op_id), trace->method,
trace->rpc_stats.elapsed_time_ms);
census_ht_erase(g_trace_store, op_id_as_key(&op_id));
diff --git a/src/core/statistics/hash_table.c b/src/core/statistics/hash_table.c
index f0105ee683..1aee86d3a4 100644
--- a/src/core/statistics/hash_table.c
+++ b/src/core/statistics/hash_table.c
@@ -141,10 +141,10 @@ static gpr_int32 find_bucket_idx(const census_ht* ht, census_ht_key key) {
static int keys_match(const census_ht_option* opt, const ht_entry* p,
const census_ht_key key) {
+ GPR_ASSERT(opt->key_type == CENSUS_HT_UINT64 ||
+ opt->key_type == CENSUS_HT_POINTER);
if (opt->key_type == CENSUS_HT_UINT64) return p->key.val == key.val;
- if (opt->key_type == CENSUS_HT_POINTER)
- return !opt->compare_keys((p->key).ptr, key.ptr);
- return 0;
+ return !opt->compare_keys((p->key).ptr, key.ptr);
}
static entry_locator ht_find(const census_ht* ht, census_ht_key key) {
diff --git a/src/core/support/alloc.c b/src/core/support/alloc.c
index 658408f334..ddf6789773 100644
--- a/src/core/support/alloc.c
+++ b/src/core/support/alloc.c
@@ -62,6 +62,4 @@ void *gpr_malloc_aligned(size_t size, size_t alignment) {
return (void *)ret;
}
-void gpr_free_aligned(void *ptr) {
- free(((void **)ptr)[-1]);
-}
+void gpr_free_aligned(void *ptr) { free(((void **)ptr)[-1]); }
diff --git a/src/core/support/cpu.h b/src/core/support/cpu.h
index 6ac0db35e5..2435ec0353 100644
--- a/src/core/support/cpu.h
+++ b/src/core/support/cpu.h
@@ -46,4 +46,4 @@ int gpr_cpu_num_cores();
[0, gpr_cpu_num_cores() - 1] */
int gpr_cpu_current_cpu();
-#endif /* __GRPC_INTERNAL_SUPPORT_CPU_H__ */
+#endif /* __GRPC_INTERNAL_SUPPORT_CPU_H__ */
diff --git a/src/core/support/cpu_linux.c b/src/core/support/cpu_linux.c
index 4d538a5b1b..922b61c3c5 100644
--- a/src/core/support/cpu_linux.c
+++ b/src/core/support/cpu_linux.c
@@ -37,13 +37,37 @@
#include "src/core/support/cpu.h"
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#define GRPC_GNU_SOURCE
+#endif
+
+#ifndef __USE_GNU
#define __USE_GNU
+#define GRPC_USE_GNU
+#endif
+
+#ifndef __USE_MISC
#define __USE_MISC
+#define GRPC_USE_MISC
+#endif
+
#include <sched.h>
+
+#ifdef GRPC_GNU_SOURCE
#undef _GNU_SOURCE
+#undef GRPC_GNU_SOURCE
+#endif
+
+#ifdef GRPC_USE_GNU
#undef __USE_GNU
+#undef GRPC_USE_GNU
+#endif
+
+#ifdef GRPC_USE_MISC
#undef __USE_MISC
+#undef GRPC_USE_MISC
+#endif
#include <errno.h>
#include <unistd.h>
diff --git a/src/core/support/log.c b/src/core/support/log.c
index b9e2897efc..7f102efea8 100644
--- a/src/core/support/log.c
+++ b/src/core/support/log.c
@@ -34,6 +34,10 @@
#include <grpc/support/log.h>
#include <stdio.h>
+#include <string.h>
+
+extern void gpr_default_log(gpr_log_func_args *args);
+static gpr_log_func g_log_func = gpr_default_log;
const char *gpr_log_severity_string(gpr_log_severity severity) {
switch (severity) {
@@ -47,12 +51,15 @@ const char *gpr_log_severity_string(gpr_log_severity severity) {
return "UNKNOWN";
}
-void gpr_log(const char *file, int line, gpr_log_severity severity,
- const char *format, ...) {
- va_list args;
- va_start(args, format);
-
- gpr_vlog(file, line, severity, format, args);
-
- va_end(args);
+void gpr_log_message(const char *file, int line, gpr_log_severity severity,
+ const char *message) {
+ gpr_log_func_args lfargs;
+ memset(&lfargs, 0, sizeof(lfargs));
+ lfargs.file = file;
+ lfargs.line = line;
+ lfargs.severity = severity;
+ lfargs.message = message;
+ g_log_func(&lfargs);
}
+
+void gpr_set_log_function(gpr_log_func f) { g_log_func = f; }
diff --git a/src/core/support/log_android.c b/src/core/support/log_android.c
index 4c83e09914..11129e3e06 100644
--- a/src/core/support/log_android.c
+++ b/src/core/support/log_android.c
@@ -54,25 +54,31 @@ static android_LogPriority severity_to_log_priority(gpr_log_severity severity) {
return ANDROID_LOG_DEFAULT;
}
-void gpr_vlog(const char *file, int line, gpr_log_severity severity,
- const char *format, va_list args) {
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+ const char *format, ...) {
+ char *message = NULL;
+ va_list args;
+ va_start(args, format);
+ vasprintf(&message, format, args);
+ va_end(args);
+ gpr_log_message(file, line, severity, message);
+ free(message);
+}
+
+void gpr_default_log(gpr_log_func_args *args) {
char *final_slash;
const char *display_file;
- char *prefix = NULL;
- char *suffix = NULL;
char *output = NULL;
- final_slash = strrchr(file, '/');
+ final_slash = strrchr(args->file, '/');
if (final_slash == NULL)
display_file = file;
else
display_file = final_slash + 1;
- asprintf(&prefix, "%s:%d] ", display_file, line);
- vasprintf(&suffix, format, args);
- asprintf(&output, "%s%s", prefix, suffix);
+ asprintf(&prefix, "%s:%d] %s", display_file, args->line, args->message);
- __android_log_write(severity_to_log_priority(severity), "GRPC", output);
+ __android_log_write(severity_to_log_priority(args->severity), "GRPC", output);
/* allocated by asprintf => use free, not gpr_free */
free(prefix);
diff --git a/src/core/support/log_linux.c b/src/core/support/log_linux.c
index 322ff07dd9..36fb4b5051 100644
--- a/src/core/support/log_linux.c
+++ b/src/core/support/log_linux.c
@@ -49,17 +49,30 @@
static long gettid() { return syscall(__NR_gettid); }
-void gpr_vlog(const char *file, int line, gpr_log_severity severity,
- const char *format, va_list args) {
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+ const char *format, ...) {
+ char *message = NULL;
+ va_list args;
+ va_start(args, format);
+ if (vasprintf(&message, format, args) == -1) {
+ va_end(args);
+ return;
+ }
+ va_end(args);
+ gpr_log_message(file, line, severity, message);
+ free(message);
+}
+
+void gpr_default_log(gpr_log_func_args *args) {
char *final_slash;
const char *display_file;
char time_buffer[64];
gpr_timespec now = gpr_now();
struct tm tm;
- final_slash = strrchr(file, '/');
+ final_slash = strrchr(args->file, '/');
if (final_slash == NULL)
- display_file = file;
+ display_file = args->file;
else
display_file = final_slash + 1;
@@ -70,12 +83,10 @@ void gpr_vlog(const char *file, int line, gpr_log_severity severity,
strcpy(time_buffer, "error:strftime");
}
- flockfile(stderr);
- fprintf(stderr, "%s%s.%09d %7ld %s:%d] ", gpr_log_severity_string(severity),
- time_buffer, (int)(now.tv_nsec), gettid(), display_file, line);
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
- funlockfile(stderr);
+ fprintf(stderr, "%s%s.%09d %7ld %s:%d] %s\n",
+ gpr_log_severity_string(args->severity), time_buffer,
+ (int)(now.tv_nsec), gettid(), display_file, args->line,
+ args->message);
}
#endif
diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c
index b47c433cd7..0420570a3e 100644
--- a/src/core/support/log_posix.c
+++ b/src/core/support/log_posix.c
@@ -47,17 +47,40 @@
static long gettid() { return pthread_self(); }
-void gpr_vlog(const char *file, int line, gpr_log_severity severity,
- const char *format, va_list args) {
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+ const char *format, ...) {
+ char buf[64];
+ char *allocated = NULL;
+ char *message = NULL;
+ int ret;
+ va_list args;
+ va_start(args, format);
+ ret = vsnprintf(buf, format, args);
+ va_end(args);
+ if (ret < 0) {
+ message = NULL;
+ } else if (ret <= sizeof(buf) - 1) {
+ message = buf;
+ } else {
+ message = allocated = gpr_malloc(ret + 1);
+ va_start(args, format);
+ vsnprintf(message, format, args);
+ va_end(args);
+ }
+ gpr_log_message(file, line, severity, message);
+ gpr_free(allocated);
+}
+
+void gpr_default_log(gpr_log_func_args *args) {
char *final_slash;
const char *display_file;
char time_buffer[64];
gpr_timespec now = gpr_now();
struct tm tm;
- final_slash = strrchr(file, '/');
+ final_slash = strrchr(args->file, '/');
if (final_slash == NULL)
- display_file = file;
+ display_file = args->file;
else
display_file = final_slash + 1;
@@ -68,12 +91,10 @@ void gpr_vlog(const char *file, int line, gpr_log_severity severity,
strcpy(time_buffer, "error:strftime");
}
- flockfile(stderr);
- fprintf(stderr, "%s%s.%09d %7ld %s:%d] ", gpr_log_severity_string(severity),
- time_buffer, (int)(now.tv_nsec), gettid(), display_file, line);
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
- funlockfile(stderr);
+ fprintf(stderr, "%s%s.%09d %7ld %s:%d] %s\n",
+ gpr_log_severity_string(args->severity), time_buffer,
+ (int)(now.tv_nsec), gettid(), display_file, args->line,
+ args->message);
}
#endif /* defined(GPR_POSIX_LOG) */
diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c
index e6567dca7e..ae5f23a90d 100644
--- a/src/core/support/log_win32.c
+++ b/src/core/support/log_win32.c
@@ -39,12 +39,42 @@
#include <stdio.h>
#include <stdarg.h>
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+ const char *message) {
+ const char *message = NULL;
+ va_list args;
+ int ret;
+
+ /* Determine the length. */
+ va_start(args, format);
+ ret = _vscprintf(format, args);
+ va_end(args);
+ if (!(0 <= ret && ret < ~(size_t)0)) {
+ message = NULL;
+ } else {
+ /* Allocate a new buffer, with space for the NUL terminator. */
+ strp_buflen = (size_t)ret + 1;
+ message = gpr_malloc(strp_buflen);
+
+ /* Print to the buffer. */
+ va_start(args, format);
+ ret = vsnprintf_s(message, strp_buflen, _TRUNCATE, format, args);
+ va_end(args);
+ if (ret != strp_buflen - 1) {
+ /* This should never happen. */
+ gpr_free(message);
+ message = NULL;
+ }
+ }
+
+ gpr_log_message(file, line, severity, message);
+ gpr_free(message);
+}
+
/* Simple starter implementation */
-void gpr_vlog(const char *file, int line, gpr_log_severity severity,
- const char *format, va_list args) {
- fprintf(stderr, "%s %s:%d: ", gpr_log_severity_string(severity), file, line);
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
+void gpr_default_log(gpr_log_func_args *args) {
+ fprintf(stderr, "%s %s:%d: %s\n", gpr_log_severity_string(severity),
+ args->file, args->line, args->message);
}
#endif
diff --git a/src/core/support/murmur_hash.h b/src/core/support/murmur_hash.h
index 5643717cd2..2ebf3e57b1 100644
--- a/src/core/support/murmur_hash.h
+++ b/src/core/support/murmur_hash.h
@@ -41,4 +41,4 @@
/* compute the hash of key (length len) */
gpr_uint32 gpr_murmur_hash3(const void *key, size_t len, gpr_uint32 seed);
-#endif /* __GRPC_INTERNAL_SUPPORT_MURMUR_HASH_H__ */
+#endif /* __GRPC_INTERNAL_SUPPORT_MURMUR_HASH_H__ */
diff --git a/src/core/support/thd_internal.h b/src/core/support/thd_internal.h
index 519177a555..190d4e3668 100644
--- a/src/core/support/thd_internal.h
+++ b/src/core/support/thd_internal.h
@@ -36,4 +36,4 @@
/* Internal interfaces between modules within the gpr support library. */
-#endif /* __GRPC_INTERNAL_SUPPORT_THD_INTERNAL_H__ */
+#endif /* __GRPC_INTERNAL_SUPPORT_THD_INTERNAL_H__ */
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index f6d93bd957..297d9587eb 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -202,7 +202,7 @@ struct grpc_call {
gpr_refcount internal_refcount;
};
-#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call)+1))
+#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1))
#define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1)
#define CALL_ELEM_FROM_CALL(call, idx) \
grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
index 5c2ef3be18..01605bb38a 100644
--- a/src/core/surface/call.h
+++ b/src/core/surface/call.h
@@ -73,4 +73,4 @@ grpc_metadata_buffer *grpc_call_get_metadata_buffer(grpc_call *call);
void grpc_call_add_mdelem(grpc_call *call, grpc_mdelem *mdelem,
gpr_uint32 flags);
-#endif /* __GRPC_INTERNAL_SURFACE_CALL_H__ */
+#endif /* __GRPC_INTERNAL_SURFACE_CALL_H__ */
diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
index 8ef13675fe..a1bcea58dd 100644
--- a/src/core/surface/channel.c
+++ b/src/core/surface/channel.c
@@ -51,7 +51,7 @@ struct grpc_channel {
grpc_mdstr *authority_string;
};
-#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c)+1))
+#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c) + 1))
grpc_channel *grpc_channel_create_from_filters(
const grpc_channel_filter **filters, size_t num_filters,
diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h
index 11d4939916..b3ea2ede40 100644
--- a/src/core/surface/channel.h
+++ b/src/core/surface/channel.h
@@ -48,4 +48,4 @@ grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel);
void grpc_channel_internal_ref(grpc_channel *channel);
void grpc_channel_internal_unref(grpc_channel *channel);
-#endif /* __GRPC_INTERNAL_SURFACE_CHANNEL_H__ */
+#endif /* __GRPC_INTERNAL_SURFACE_CHANNEL_H__ */
diff --git a/src/core/surface/client.c b/src/core/surface/client.c
index 98cb460d63..524b0718a9 100644
--- a/src/core/surface/client.c
+++ b/src/core/surface/client.c
@@ -106,13 +106,12 @@ static void init_channel_elem(grpc_channel_element *elem,
GPR_ASSERT(!is_last);
}
-static void destroy_channel_elem(grpc_channel_element *elem) {
-}
+static void destroy_channel_elem(grpc_channel_element *elem) {}
const grpc_channel_filter grpc_client_surface_filter = {
- call_op, channel_op,
+ call_op, channel_op,
- sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
diff --git a/src/core/surface/client.h b/src/core/surface/client.h
index eb567276e2..cff3d401d9 100644
--- a/src/core/surface/client.h
+++ b/src/core/surface/client.h
@@ -38,4 +38,4 @@
extern const grpc_channel_filter grpc_client_surface_filter;
-#endif /* __GRPC_INTERNAL_SURFACE_CLIENT_H__ */
+#endif /* __GRPC_INTERNAL_SURFACE_CLIENT_H__ */
diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h
index 2e752a3fe0..5e45749396 100644
--- a/src/core/surface/completion_queue.h
+++ b/src/core/surface/completion_queue.h
@@ -104,4 +104,4 @@ void grpc_cq_dump_pending_ops(grpc_completion_queue *cc);
grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc);
-#endif /* __GRPC_INTERNAL_SURFACE_COMPLETION_QUEUE_H__ */
+#endif /* __GRPC_INTERNAL_SURFACE_COMPLETION_QUEUE_H__ */
diff --git a/src/core/surface/event_string.h b/src/core/surface/event_string.h
index 30b693e95c..b34e2d152b 100644
--- a/src/core/surface/event_string.h
+++ b/src/core/surface/event_string.h
@@ -39,4 +39,4 @@
/* Returns a string describing an event. Must be later freed with gpr_free() */
char *grpc_event_string(grpc_event *ev);
-#endif /* __GRPC_INTERNAL_SURFACE_EVENT_STRING_H__ */
+#endif /* __GRPC_INTERNAL_SURFACE_EVENT_STRING_H__ */
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
index 6a832436ca..5fa3e42362 100644
--- a/src/core/surface/lame_client.c
+++ b/src/core/surface/lame_client.c
@@ -33,6 +33,8 @@
#include "src/core/surface/lame_client.h"
+#include <string.h>
+
#include "src/core/channel/channel_stack.h"
#include "src/core/surface/channel.h"
#include "src/core/surface/call.h"
@@ -42,16 +44,28 @@
typedef struct { void *unused; } call_data;
-typedef struct { void *unused; } channel_data;
+typedef struct { grpc_mdelem *message; } channel_data;
+
+static void do_nothing(void *data, grpc_op_error error) {}
static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
grpc_call_op *op) {
+ channel_data *channeld = elem->channel_data;
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
switch (op->type) {
- case GRPC_SEND_START:
+ case GRPC_SEND_START: {
+ grpc_call_op set_status_op;
+ grpc_mdelem_ref(channeld->message);
+ memset(&set_status_op, 0, sizeof(grpc_call_op));
+ set_status_op.dir = GRPC_CALL_UP;
+ set_status_op.type = GRPC_RECV_METADATA;
+ set_status_op.done_cb = do_nothing;
+ set_status_op.data.metadata = channeld->message;
+ grpc_call_recv_metadata(elem, &set_status_op);
grpc_call_recv_finish(elem, 1);
break;
+ }
case GRPC_SEND_METADATA:
grpc_mdelem_unref(op->data.metadata);
break;
@@ -81,11 +95,20 @@ static void destroy_call_elem(grpc_call_element *elem) {}
static void init_channel_elem(grpc_channel_element *elem,
const grpc_channel_args *args, grpc_mdctx *mdctx,
int is_first, int is_last) {
+ channel_data *channeld = elem->channel_data;
+
GPR_ASSERT(is_first);
GPR_ASSERT(is_last);
+
+ channeld->message = grpc_mdelem_from_strings(mdctx, "grpc-message",
+ "Rpc sent on a lame channel.");
}
-static void destroy_channel_elem(grpc_channel_element *elem) {}
+static void destroy_channel_elem(grpc_channel_element *elem) {
+ channel_data *channeld = elem->channel_data;
+
+ grpc_mdelem_unref(channeld->message);
+}
static const grpc_channel_filter lame_filter = {
call_op, channel_op,
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index aa544a97f2..167bfe97d1 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -405,9 +405,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
static const grpc_channel_filter server_surface_filter = {
- call_op, channel_op,
+ call_op, channel_op,
- sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
diff --git a/src/core/surface/server.h b/src/core/surface/server.h
index 61292ebe4e..50574d66a4 100644
--- a/src/core/surface/server.h
+++ b/src/core/surface/server.h
@@ -60,4 +60,4 @@ grpc_transport_setup_result grpc_server_setup_transport(
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
-#endif /* __GRPC_INTERNAL_SURFACE_SERVER_H__ */
+#endif /* __GRPC_INTERNAL_SURFACE_SERVER_H__ */
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
index a0961bd449..47fca827f3 100644
--- a/src/core/surface/server_chttp2.c
+++ b/src/core/surface/server_chttp2.c
@@ -76,6 +76,8 @@ int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
grpc_tcp_server *tcp = NULL;
size_t i;
int count = 0;
+ int port_num = -1;
+ int port_temp;
resolved = grpc_blocking_resolve_address(addr, "http");
if (!resolved) {
@@ -88,9 +90,15 @@ int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
}
for (i = 0; i < resolved->naddrs; i++) {
- if (grpc_tcp_server_add_port(tcp,
- (struct sockaddr *)&resolved->addrs[i].addr,
- resolved->addrs[i].len)) {
+ port_temp = grpc_tcp_server_add_port(
+ tcp, (struct sockaddr *)&resolved->addrs[i].addr,
+ resolved->addrs[i].len);
+ if (port_temp >= 0) {
+ if (port_num == -1) {
+ port_num = port_temp;
+ } else {
+ GPR_ASSERT(port_num == port_temp);
+ }
count++;
}
}
@@ -108,7 +116,7 @@ int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
/* Register with the server only upon success */
grpc_server_add_listener(server, tcp, start, destroy);
- return 1;
+ return port_num;
/* Error path: cleanup and return */
error:
diff --git a/src/core/surface/surface_trace.h b/src/core/surface/surface_trace.h
index f6f9acfd9c..df1aea9669 100644
--- a/src/core/surface/surface_trace.h
+++ b/src/core/surface/surface_trace.h
@@ -51,4 +51,4 @@
} while (0)
#endif
-#endif /* __GRPC_INTERNAL_SURFACE_SURFACE_TRACE_H__ */
+#endif /* __GRPC_INTERNAL_SURFACE_SURFACE_TRACE_H__ */
diff --git a/src/core/transport/chttp2/frame.h b/src/core/transport/chttp2/frame.h
index a04e442ed6..6d28638309 100644
--- a/src/core/transport/chttp2/frame.h
+++ b/src/core/transport/chttp2/frame.h
@@ -77,4 +77,4 @@ typedef struct {
#define GRPC_CHTTP2_DATA_FLAG_PADDED 8
#define GRPC_CHTTP2_FLAG_HAS_PRIORITY 0x20
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_H__ */
diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c
index fbd3b6cabf..c22a223737 100644
--- a/src/core/transport/chttp2/frame_data.c
+++ b/src/core/transport/chttp2/frame_data.c
@@ -161,4 +161,3 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
abort();
return GRPC_CHTTP2_CONNECTION_ERROR;
}
-
diff --git a/src/core/transport/chttp2/frame_data.h b/src/core/transport/chttp2/frame_data.h
index abe26dab76..c260059e8b 100644
--- a/src/core/transport/chttp2/frame_data.h
+++ b/src/core/transport/chttp2/frame_data.h
@@ -77,4 +77,4 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
/* create a slice with an empty data frame and is_last set */
gpr_slice grpc_chttp2_data_frame_create_empty_close(gpr_uint32 id);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_DATA_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_DATA_H__ */
diff --git a/src/core/transport/chttp2/frame_ping.h b/src/core/transport/chttp2/frame_ping.h
index a64d53644b..fa778c51b2 100644
--- a/src/core/transport/chttp2/frame_ping.h
+++ b/src/core/transport/chttp2/frame_ping.h
@@ -50,4 +50,4 @@ grpc_chttp2_parse_error grpc_chttp2_ping_parser_begin_frame(
grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse(
void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_PING_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_PING_H__ */
diff --git a/src/core/transport/chttp2/frame_rst_stream.h b/src/core/transport/chttp2/frame_rst_stream.h
index 78aea0f26a..dbb262971b 100644
--- a/src/core/transport/chttp2/frame_rst_stream.h
+++ b/src/core/transport/chttp2/frame_rst_stream.h
@@ -38,4 +38,4 @@
gpr_slice grpc_chttp2_rst_stream_create(gpr_uint32 stream_id, gpr_uint32 code);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H__ */
diff --git a/src/core/transport/chttp2/frame_settings.h b/src/core/transport/chttp2/frame_settings.h
index dcb8b00ca1..855f9636bb 100644
--- a/src/core/transport/chttp2/frame_settings.h
+++ b/src/core/transport/chttp2/frame_settings.h
@@ -96,4 +96,4 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame(
grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_SETTINGS_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_SETTINGS_H__ */
diff --git a/src/core/transport/chttp2/frame_window_update.h b/src/core/transport/chttp2/frame_window_update.h
index 4b789fcc4a..2d9e6c4dcb 100644
--- a/src/core/transport/chttp2/frame_window_update.h
+++ b/src/core/transport/chttp2/frame_window_update.h
@@ -52,4 +52,4 @@ grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame(
grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse(
void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H__ */
diff --git a/src/core/transport/chttp2/hpack_parser.h b/src/core/transport/chttp2/hpack_parser.h
index 799513e7ff..b0a0d76713 100644
--- a/src/core/transport/chttp2/hpack_parser.h
+++ b/src/core/transport/chttp2/hpack_parser.h
@@ -108,4 +108,4 @@ grpc_chttp2_parse_error grpc_chttp2_header_parser_parse(
void *hpack_parser, grpc_chttp2_parse_state *state, gpr_slice slice,
int is_last);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_PARSER_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_PARSER_H__ */
diff --git a/src/core/transport/chttp2/hpack_table.c b/src/core/transport/chttp2/hpack_table.c
index 8f2ebecfeb..ae8bfa8009 100644
--- a/src/core/transport/chttp2/hpack_table.c
+++ b/src/core/transport/chttp2/hpack_table.c
@@ -43,68 +43,68 @@ static struct {
const char *key;
const char *value;
} static_table[] = {
- /* 0: */ {NULL, NULL},
- /* 1: */ {":authority", ""},
- /* 2: */ {":method", "GET"},
- /* 3: */ {":method", "POST"},
- /* 4: */ {":path", "/"},
- /* 5: */ {":path", "/index.html"},
- /* 6: */ {":scheme", "http"},
- /* 7: */ {":scheme", "https"},
- /* 8: */ {":status", "200"},
- /* 9: */ {":status", "204"},
- /* 10: */ {":status", "206"},
- /* 11: */ {":status", "304"},
- /* 12: */ {":status", "400"},
- /* 13: */ {":status", "404"},
- /* 14: */ {":status", "500"},
- /* 15: */ {"accept-charset", ""},
- /* 16: */ {"accept-encoding", "gzip, deflate"},
- /* 17: */ {"accept-language", ""},
- /* 18: */ {"accept-ranges", ""},
- /* 19: */ {"accept", ""},
- /* 20: */ {"access-control-allow-origin", ""},
- /* 21: */ {"age", ""},
- /* 22: */ {"allow", ""},
- /* 23: */ {"authorization", ""},
- /* 24: */ {"cache-control", ""},
- /* 25: */ {"content-disposition", ""},
- /* 26: */ {"content-encoding", ""},
- /* 27: */ {"content-language", ""},
- /* 28: */ {"content-length", ""},
- /* 29: */ {"content-location", ""},
- /* 30: */ {"content-range", ""},
- /* 31: */ {"content-type", ""},
- /* 32: */ {"cookie", ""},
- /* 33: */ {"date", ""},
- /* 34: */ {"etag", ""},
- /* 35: */ {"expect", ""},
- /* 36: */ {"expires", ""},
- /* 37: */ {"from", ""},
- /* 38: */ {"host", ""},
- /* 39: */ {"if-match", ""},
- /* 40: */ {"if-modified-since", ""},
- /* 41: */ {"if-none-match", ""},
- /* 42: */ {"if-range", ""},
- /* 43: */ {"if-unmodified-since", ""},
- /* 44: */ {"last-modified", ""},
- /* 45: */ {"link", ""},
- /* 46: */ {"location", ""},
- /* 47: */ {"max-forwards", ""},
- /* 48: */ {"proxy-authenticate", ""},
- /* 49: */ {"proxy-authorization", ""},
- /* 50: */ {"range", ""},
- /* 51: */ {"referer", ""},
- /* 52: */ {"refresh", ""},
- /* 53: */ {"retry-after", ""},
- /* 54: */ {"server", ""},
- /* 55: */ {"set-cookie", ""},
- /* 56: */ {"strict-transport-security", ""},
- /* 57: */ {"transfer-encoding", ""},
- /* 58: */ {"user-agent", ""},
- /* 59: */ {"vary", ""},
- /* 60: */ {"via", ""},
- /* 61: */ {"www-authenticate", ""},
+ /* 0: */ {NULL, NULL},
+ /* 1: */ {":authority", ""},
+ /* 2: */ {":method", "GET"},
+ /* 3: */ {":method", "POST"},
+ /* 4: */ {":path", "/"},
+ /* 5: */ {":path", "/index.html"},
+ /* 6: */ {":scheme", "http"},
+ /* 7: */ {":scheme", "https"},
+ /* 8: */ {":status", "200"},
+ /* 9: */ {":status", "204"},
+ /* 10: */ {":status", "206"},
+ /* 11: */ {":status", "304"},
+ /* 12: */ {":status", "400"},
+ /* 13: */ {":status", "404"},
+ /* 14: */ {":status", "500"},
+ /* 15: */ {"accept-charset", ""},
+ /* 16: */ {"accept-encoding", "gzip, deflate"},
+ /* 17: */ {"accept-language", ""},
+ /* 18: */ {"accept-ranges", ""},
+ /* 19: */ {"accept", ""},
+ /* 20: */ {"access-control-allow-origin", ""},
+ /* 21: */ {"age", ""},
+ /* 22: */ {"allow", ""},
+ /* 23: */ {"authorization", ""},
+ /* 24: */ {"cache-control", ""},
+ /* 25: */ {"content-disposition", ""},
+ /* 26: */ {"content-encoding", ""},
+ /* 27: */ {"content-language", ""},
+ /* 28: */ {"content-length", ""},
+ /* 29: */ {"content-location", ""},
+ /* 30: */ {"content-range", ""},
+ /* 31: */ {"content-type", ""},
+ /* 32: */ {"cookie", ""},
+ /* 33: */ {"date", ""},
+ /* 34: */ {"etag", ""},
+ /* 35: */ {"expect", ""},
+ /* 36: */ {"expires", ""},
+ /* 37: */ {"from", ""},
+ /* 38: */ {"host", ""},
+ /* 39: */ {"if-match", ""},
+ /* 40: */ {"if-modified-since", ""},
+ /* 41: */ {"if-none-match", ""},
+ /* 42: */ {"if-range", ""},
+ /* 43: */ {"if-unmodified-since", ""},
+ /* 44: */ {"last-modified", ""},
+ /* 45: */ {"link", ""},
+ /* 46: */ {"location", ""},
+ /* 47: */ {"max-forwards", ""},
+ /* 48: */ {"proxy-authenticate", ""},
+ /* 49: */ {"proxy-authorization", ""},
+ /* 50: */ {"range", ""},
+ /* 51: */ {"referer", ""},
+ /* 52: */ {"refresh", ""},
+ /* 53: */ {"retry-after", ""},
+ /* 54: */ {"server", ""},
+ /* 55: */ {"set-cookie", ""},
+ /* 56: */ {"strict-transport-security", ""},
+ /* 57: */ {"transfer-encoding", ""},
+ /* 58: */ {"user-agent", ""},
+ /* 59: */ {"vary", ""},
+ /* 60: */ {"via", ""},
+ /* 61: */ {"www-authenticate", ""},
};
void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl, grpc_mdctx *mdctx) {
diff --git a/src/core/transport/chttp2/hpack_table.h b/src/core/transport/chttp2/hpack_table.h
index a3a07ad014..84a8e2d1e0 100644
--- a/src/core/transport/chttp2/hpack_table.h
+++ b/src/core/transport/chttp2/hpack_table.h
@@ -94,4 +94,4 @@ typedef struct {
grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
const grpc_chttp2_hptbl *tbl, grpc_mdelem *md);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_TABLE_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_TABLE_H__ */
diff --git a/src/core/transport/chttp2/http2_errors.h b/src/core/transport/chttp2/http2_errors.h
index d065422c6f..7791da6d5a 100644
--- a/src/core/transport/chttp2/http2_errors.h
+++ b/src/core/transport/chttp2/http2_errors.h
@@ -53,4 +53,4 @@ typedef enum {
GRPC_CHTTP2__ERROR_DO_NOT_USE = -1
} grpc_chttp2_error_code;
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HTTP2_ERRORS_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HTTP2_ERRORS_H__ */
diff --git a/src/core/transport/chttp2/status_conversion.h b/src/core/transport/chttp2/status_conversion.h
index ae9e7f2ca3..f78d81e0aa 100644
--- a/src/core/transport/chttp2/status_conversion.h
+++ b/src/core/transport/chttp2/status_conversion.h
@@ -47,4 +47,4 @@ grpc_status_code grpc_chttp2_http2_error_to_grpc_status(
grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status);
int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STATUS_CONVERSION_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STATUS_CONVERSION_H__ */
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index 8595a59879..92a36d0c16 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -68,8 +68,6 @@ typedef struct {
gpr_uint8 last_was_header;
/* output stream id */
gpr_uint32 stream_id;
- /* number of flow controlled bytes written */
- gpr_uint32 output_size;
gpr_slice_buffer *output;
} framer_state;
@@ -464,49 +462,31 @@ void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
grpc_mdstr_unref(c->timeout_key_str);
}
-gpr_uint32 grpc_chttp2_encode_some(grpc_stream_op *ops, size_t *ops_count,
- int eof, gpr_slice_buffer *output,
- gpr_uint32 max_bytes, gpr_uint32 stream_id,
- grpc_chttp2_hpack_compressor *compressor) {
- framer_state st;
+gpr_uint32 grpc_chttp2_preencode(grpc_stream_op *inops, size_t *inops_count,
+ gpr_uint32 max_flow_controlled_bytes,
+ grpc_stream_op_buffer *outops) {
gpr_slice slice;
grpc_stream_op *op;
gpr_uint32 max_take_size;
+ gpr_uint32 flow_controlled_bytes_taken = 0;
gpr_uint32 curop = 0;
- gpr_uint32 nops = *ops_count;
gpr_uint8 *p;
- GPR_ASSERT(stream_id != 0);
-
- st.cur_frame_type = NONE;
- st.last_was_header = 0;
- st.stream_id = stream_id;
- st.output = output;
- st.output_size = 0;
-
- while (curop < nops) {
- GPR_ASSERT(st.output_size <= max_bytes);
- op = &ops[curop];
+ while (curop < *inops_count) {
+ GPR_ASSERT(flow_controlled_bytes_taken <= max_flow_controlled_bytes);
+ op = &inops[curop];
switch (op->type) {
case GRPC_NO_OP:
+ /* skip */
curop++;
break;
case GRPC_OP_FLOW_CTL_CB:
- op->data.flow_ctl_cb.cb(op->data.flow_ctl_cb.arg, GRPC_OP_OK);
- curop++;
- break;
- case GRPC_OP_METADATA:
- hpack_enc(compressor, op->data.metadata, &st);
- curop++;
- break;
case GRPC_OP_DEADLINE:
- deadline_enc(compressor, op->data.deadline, &st);
- curop++;
- break;
+ case GRPC_OP_METADATA:
case GRPC_OP_METADATA_BOUNDARY:
- ensure_frame_type(&st, HEADER, 0);
- finish_frame(&st, 1, 0);
- st.last_was_header = 0; /* force a new header frame */
+ /* these just get copied as they don't impact the number of flow
+ controlled bytes */
+ grpc_sopb_append(outops, op, 1);
curop++;
break;
case GRPC_OP_BEGIN_MESSAGE:
@@ -525,42 +505,100 @@ gpr_uint32 grpc_chttp2_encode_some(grpc_stream_op *ops, size_t *ops_count,
case GRPC_OP_SLICE:
slice = op->data.slice;
if (!GPR_SLICE_LENGTH(slice)) {
+ /* skip zero length slices */
+ gpr_slice_unref(slice);
curop++;
break;
}
- if (st.output_size == max_bytes) {
+ max_take_size = max_flow_controlled_bytes - flow_controlled_bytes_taken;
+ if (max_take_size == 0) {
goto exit_loop;
}
+ if (GPR_SLICE_LENGTH(slice) > max_take_size) {
+ slice = gpr_slice_split_head(&op->data.slice, max_take_size);
+ grpc_sopb_add_slice(outops, slice);
+ } else {
+ /* consume this op immediately */
+ grpc_sopb_append(outops, op, 1);
+ curop++;
+ }
+ flow_controlled_bytes_taken += GPR_SLICE_LENGTH(slice);
+ break;
+ }
+ }
+exit_loop:
+ *inops_count -= curop;
+ memmove(inops, inops + curop, *inops_count * sizeof(grpc_stream_op));
+
+ return flow_controlled_bytes_taken;
+}
+
+void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
+ gpr_uint32 stream_id,
+ grpc_chttp2_hpack_compressor *compressor,
+ gpr_slice_buffer *output) {
+ framer_state st;
+ gpr_slice slice;
+ grpc_stream_op *op;
+ gpr_uint32 max_take_size;
+ gpr_uint32 curop = 0;
+
+ GPR_ASSERT(stream_id != 0);
+
+ st.cur_frame_type = NONE;
+ st.last_was_header = 0;
+ st.stream_id = stream_id;
+ st.output = output;
+
+ while (curop < ops_count) {
+ op = &ops[curop];
+ switch (op->type) {
+ case GRPC_NO_OP:
+ case GRPC_OP_BEGIN_MESSAGE:
+ gpr_log(
+ GPR_ERROR,
+ "These stream ops should be filtered out by grpc_chttp2_preencode");
+ abort();
+ case GRPC_OP_FLOW_CTL_CB:
+ op->data.flow_ctl_cb.cb(op->data.flow_ctl_cb.arg, GRPC_OP_OK);
+ curop++;
+ break;
+ case GRPC_OP_METADATA:
+ hpack_enc(compressor, op->data.metadata, &st);
+ curop++;
+ break;
+ case GRPC_OP_DEADLINE:
+ deadline_enc(compressor, op->data.deadline, &st);
+ curop++;
+ break;
+ case GRPC_OP_METADATA_BOUNDARY:
+ ensure_frame_type(&st, HEADER, 0);
+ finish_frame(&st, 1, 0);
+ st.last_was_header = 0; /* force a new header frame */
+ curop++;
+ break;
+ case GRPC_OP_SLICE:
+ slice = op->data.slice;
if (st.cur_frame_type == DATA &&
st.output->length - st.output_length_at_start_of_frame ==
GRPC_CHTTP2_MAX_PAYLOAD_LENGTH) {
finish_frame(&st, 0, 0);
}
ensure_frame_type(&st, DATA, 1);
- max_take_size =
- GPR_MIN(max_bytes - st.output_size,
- GRPC_CHTTP2_MAX_PAYLOAD_LENGTH +
- st.output_length_at_start_of_frame - st.output->length);
+ max_take_size = GRPC_CHTTP2_MAX_PAYLOAD_LENGTH +
+ st.output_length_at_start_of_frame - st.output->length;
if (GPR_SLICE_LENGTH(slice) > max_take_size) {
slice = gpr_slice_split_head(&op->data.slice, max_take_size);
} else {
/* consume this op immediately */
curop++;
}
- st.output_size += GPR_SLICE_LENGTH(slice);
gpr_slice_buffer_add(output, slice);
break;
}
}
-exit_loop:
if (eof && st.cur_frame_type == NONE) {
begin_frame(&st, DATA);
}
- finish_frame(&st, 1, eof && curop == nops);
-
- nops -= curop;
- *ops_count = nops;
- memmove(ops, ops + curop, nops * sizeof(grpc_stream_op));
-
- return st.output_size;
+ finish_frame(&st, 1, eof);
}
diff --git a/src/core/transport/chttp2/stream_encoder.h b/src/core/transport/chttp2/stream_encoder.h
index dad64697a5..147b1d31ff 100644
--- a/src/core/transport/chttp2/stream_encoder.h
+++ b/src/core/transport/chttp2/stream_encoder.h
@@ -78,9 +78,16 @@ void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c,
grpc_mdctx *mdctx);
void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c);
-gpr_uint32 grpc_chttp2_encode_some(grpc_stream_op *ops, size_t *ops_count,
- int eof, gpr_slice_buffer *output,
- gpr_uint32 max_bytes, gpr_uint32 stream_id,
- grpc_chttp2_hpack_compressor *compressor);
+/* select stream ops to be encoded, moving them from inops to outops, and
+ moving subsequent ops in inops forward in the queue */
+gpr_uint32 grpc_chttp2_preencode(grpc_stream_op *inops, size_t *inops_count,
+ gpr_uint32 max_flow_controlled_bytes,
+ grpc_stream_op_buffer *outops);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_ENCODER_H__ */
+/* encode stream ops to output */
+void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
+ gpr_uint32 stream_id,
+ grpc_chttp2_hpack_compressor *compressor,
+ gpr_slice_buffer *output);
+
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_ENCODER_H__ */
diff --git a/src/core/transport/chttp2/stream_map.h b/src/core/transport/chttp2/stream_map.h
index caaee30676..03bf719f37 100644
--- a/src/core/transport/chttp2/stream_map.h
+++ b/src/core/transport/chttp2/stream_map.h
@@ -78,4 +78,4 @@ void grpc_chttp2_stream_map_for_each(grpc_chttp2_stream_map *map,
void *value),
void *user_data);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_MAP_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_MAP_H__ */
diff --git a/src/core/transport/chttp2/varint.h b/src/core/transport/chttp2/varint.h
index 780390238f..940df00a99 100644
--- a/src/core/transport/chttp2/varint.h
+++ b/src/core/transport/chttp2/varint.h
@@ -70,4 +70,4 @@ void grpc_chttp2_hpack_write_varint_tail(gpr_uint32 tail_value,
} \
} while (0)
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_VARINT_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_VARINT_H__ */
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 5bf763e76f..1b90d4715b 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -71,6 +71,13 @@ typedef struct stream stream;
typedef enum {
/* streams that have pending writes */
WRITABLE = 0,
+ /* streams that have been selected to be written */
+ WRITING,
+ /* streams that have just been written, and included a close */
+ WRITTEN_CLOSED,
+ /* streams that have been cancelled and have some pending state updates
+ to perform */
+ CANCELLED,
/* streams that want to send window updates */
WINDOW_UPDATE,
/* streams that are waiting to start because there are too many concurrent
@@ -258,7 +265,12 @@ struct stream {
gpr_uint32 outgoing_window;
gpr_uint32 incoming_window;
- gpr_uint8 write_closed;
+ /* when the application requests writes be closed, the write_closed is
+ 'queued'; when the close is flow controlled into the send path, we are
+ 'sending' it; when the write has been performed it is 'sent' */
+ gpr_uint8 queued_write_closed;
+ gpr_uint8 sending_write_closed;
+ gpr_uint8 sent_write_closed;
gpr_uint8 read_closed;
gpr_uint8 cancelled;
gpr_uint8 allow_window_updates;
@@ -267,7 +279,10 @@ struct stream {
stream_link links[STREAM_LIST_COUNT];
gpr_uint8 included[STREAM_LIST_COUNT];
+ /* sops from application */
grpc_stream_op_buffer outgoing_sopb;
+ /* sops that have passed flow control to be written */
+ grpc_stream_op_buffer writing_sopb;
grpc_chttp2_data_parser parser;
@@ -284,7 +299,7 @@ static int prepare_callbacks(transport *t);
static void run_callbacks(transport *t);
static int prepare_write(transport *t);
-static void finish_write(void *t, grpc_endpoint_cb_status status);
+static void perform_write(transport *t, grpc_endpoint *ep);
static void lock(transport *t);
static void unlock(transport *t);
@@ -303,6 +318,7 @@ static void cancel_stream_id(transport *t, gpr_uint32 id,
static void cancel_stream(transport *t, stream *s,
grpc_status_code local_status,
grpc_chttp2_error_code error_code, int send_rst);
+static void finalize_cancellations(transport *t);
static stream *lookup_stream(transport *t, gpr_uint32 id);
static void remove_from_stream_map(transport *t, stream *s);
static void maybe_start_some_streams(transport *t);
@@ -518,7 +534,9 @@ static int init_stream(grpc_transport *gt, grpc_stream *gs,
t->settings[PEER_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
s->incoming_window =
t->settings[SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
- s->write_closed = 0;
+ s->queued_write_closed = 0;
+ s->sending_write_closed = 0;
+ s->sent_write_closed = 0;
s->read_closed = 0;
s->cancelled = 0;
s->allow_window_updates = 0;
@@ -526,8 +544,9 @@ static int init_stream(grpc_transport *gt, grpc_stream *gs,
memset(&s->links, 0, sizeof(s->links));
memset(&s->included, 0, sizeof(s->included));
grpc_sopb_init(&s->outgoing_sopb);
- grpc_chttp2_data_parser_init(&s->parser);
+ grpc_sopb_init(&s->writing_sopb);
grpc_sopb_init(&s->callback_sopb);
+ grpc_chttp2_data_parser_init(&s->parser);
if (!server_data) {
unlock(t);
@@ -565,8 +584,9 @@ static void destroy_stream(grpc_transport *gt, grpc_stream *gs) {
gpr_mu_unlock(&t->mu);
grpc_sopb_destroy(&s->outgoing_sopb);
- grpc_chttp2_data_parser_destroy(&s->parser);
+ grpc_sopb_destroy(&s->writing_sopb);
grpc_sopb_destroy(&s->callback_sopb);
+ grpc_chttp2_data_parser_destroy(&s->parser);
unref_transport(t);
}
@@ -575,6 +595,10 @@ static void destroy_stream(grpc_transport *gt, grpc_stream *gs) {
* LIST MANAGEMENT
*/
+static int stream_list_empty(transport *t, stream_list_id id) {
+ return t->lists[id].head == NULL;
+}
+
static stream *stream_list_remove_head(transport *t, stream_list_id id) {
stream *s = t->lists[id].head;
if (s) {
@@ -666,6 +690,10 @@ static void unlock(transport *t) {
}
}
+ if (!t->writing) {
+ finalize_cancellations(t);
+ }
+
/* gather any callbacks that need to be made */
if (!t->calling_back && t->cb) {
perform_callbacks = prepare_callbacks(t);
@@ -709,53 +737,9 @@ static void unlock(transport *t) {
}
/* write some bytes if necessary */
- while (start_write) {
- switch (grpc_endpoint_write(ep, t->outbuf.slices, t->outbuf.count,
- finish_write, t)) {
- case GRPC_ENDPOINT_WRITE_DONE:
- /* grab the lock directly without wrappers since we just want to
- continue writes if we loop: no need to check read callbacks again */
- gpr_mu_lock(&t->mu);
- t->outbuf.count = 0;
- t->outbuf.length = 0;
- t->writing = start_write = prepare_write(t);
- if (!start_write) {
- if (!t->reading) {
- grpc_endpoint_destroy(t->ep);
- t->ep = NULL;
- gpr_cv_broadcast(&t->cv);
- /* endpoint ref: safe because we'll still have the ref for write */
- unref_transport(t);
- }
- }
- gpr_mu_unlock(&t->mu);
- if (!start_write) {
- unref_transport(t);
- }
- break;
- case GRPC_ENDPOINT_WRITE_ERROR:
- start_write = 0;
- /* use the wrapper lock/unlock here as we drop_connection, causing
- read callbacks to be queued (which will be cleared during unlock) */
- lock(t);
- t->outbuf.count = 0;
- t->outbuf.length = 0;
- t->writing = 0;
- drop_connection(t);
- if (!t->reading) {
- grpc_endpoint_destroy(t->ep);
- t->ep = NULL;
- gpr_cv_broadcast(&t->cv);
- /* endpoint ref: safe because we'll still have the ref for write */
- unref_transport(t);
- }
- unlock(t);
- unref_transport(t);
- break;
- case GRPC_ENDPOINT_WRITE_PENDING:
- start_write = 0;
- break;
- }
+ if (start_write) {
+ /* ultimately calls unref_transport(t); and clears t->writing */
+ perform_write(t, ep);
}
if (perform_callbacks || call_closed || num_goaways) {
@@ -788,32 +772,10 @@ static void push_setting(transport *t, grpc_chttp2_setting_id id,
}
}
-static void finish_write(void *tp, grpc_endpoint_cb_status error) {
- transport *t = tp;
-
- lock(t);
- if (error != GRPC_ENDPOINT_CB_OK) {
- drop_connection(t);
- }
- t->outbuf.count = 0;
- t->outbuf.length = 0;
- /* leave the writing flag up on shutdown to prevent further writes in unlock()
- from starting */
- t->writing = 0;
- if (!t->reading) {
- grpc_endpoint_destroy(t->ep);
- t->ep = NULL;
- gpr_cv_broadcast(&t->cv);
- unref_transport(t); /* safe because we'll still have the ref for write */
- }
- unlock(t);
-
- unref_transport(t);
-}
-
static int prepare_write(transport *t) {
stream *s;
gpr_slice_buffer tempbuf;
+ gpr_uint32 window_delta;
/* simple writes are queued to qbuf, and flushed here */
tempbuf = t->qbuf;
@@ -834,17 +796,16 @@ static int prepare_write(transport *t) {
/* for each stream that's become writable, frame it's data (according to
available window sizes) and add to the output buffer */
while (t->outgoing_window && (s = stream_list_remove_head(t, WRITABLE))) {
- gpr_uint32 written = grpc_chttp2_encode_some(
- s->outgoing_sopb.ops, &s->outgoing_sopb.nops, s->write_closed,
- &t->outbuf, GPR_MIN(t->outgoing_window, s->outgoing_window), s->id,
- &t->hpack_compressor);
- t->outgoing_window -= written;
- s->outgoing_window -= written;
-
- /* if there are no more writes to do and writes are closed, we need to
- queue a callback to let the application know */
- if (s->write_closed && s->outgoing_sopb.nops == 0) {
- stream_list_join(t, s, PENDING_CALLBACKS);
+ window_delta = grpc_chttp2_preencode(
+ s->outgoing_sopb.ops, &s->outgoing_sopb.nops,
+ GPR_MIN(t->outgoing_window, s->outgoing_window), &s->writing_sopb);
+ t->outgoing_window -= window_delta;
+ s->outgoing_window -= window_delta;
+
+ s->sending_write_closed =
+ s->queued_write_closed && s->outgoing_sopb.nops == 0;
+ if (s->writing_sopb.nops > 0 || s->sending_write_closed) {
+ stream_list_join(t, s, WRITING);
}
/* if there are still writes to do and the stream still has window
@@ -857,25 +818,89 @@ static int prepare_write(transport *t) {
/* for each stream that wants to update its window, add that window here */
while ((s = stream_list_remove_head(t, WINDOW_UPDATE))) {
- gpr_uint32 window_add =
+ window_delta =
t->settings[LOCAL_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] -
s->incoming_window;
- if (!s->read_closed && window_add) {
- gpr_slice_buffer_add(&t->outbuf,
- grpc_chttp2_window_update_create(s->id, window_add));
- s->incoming_window += window_add;
+ if (!s->read_closed && window_delta) {
+ gpr_slice_buffer_add(
+ &t->outbuf, grpc_chttp2_window_update_create(s->id, window_delta));
+ s->incoming_window += window_delta;
}
}
/* if the transport is ready to send a window update, do so here also */
if (t->incoming_window < t->connection_window_target * 3 / 4) {
- gpr_uint32 window_add = t->connection_window_target - t->incoming_window;
+ window_delta = t->connection_window_target - t->incoming_window;
gpr_slice_buffer_add(&t->outbuf,
- grpc_chttp2_window_update_create(0, window_add));
- t->incoming_window += window_add;
+ grpc_chttp2_window_update_create(0, window_delta));
+ t->incoming_window += window_delta;
}
- return t->outbuf.length > 0;
+ return t->outbuf.length > 0 || !stream_list_empty(t, WRITING);
+}
+
+static void finalize_outbuf(transport *t) {
+ stream *s;
+
+ while ((s = stream_list_remove_head(t, WRITING))) {
+ grpc_chttp2_encode(s->writing_sopb.ops, s->writing_sopb.nops,
+ s->sending_write_closed, s->id, &t->hpack_compressor,
+ &t->outbuf);
+ s->writing_sopb.nops = 0;
+ if (s->sending_write_closed) {
+ stream_list_join(t, s, WRITTEN_CLOSED);
+ }
+ }
+}
+
+static void finish_write_common(transport *t, int success) {
+ stream *s;
+
+ lock(t);
+ if (!success) {
+ drop_connection(t);
+ }
+ while ((s = stream_list_remove_head(t, WRITTEN_CLOSED))) {
+ s->sent_write_closed = 1;
+ stream_list_join(t, s, PENDING_CALLBACKS);
+ }
+ t->outbuf.count = 0;
+ t->outbuf.length = 0;
+ /* leave the writing flag up on shutdown to prevent further writes in unlock()
+ from starting */
+ t->writing = 0;
+ if (!t->reading) {
+ grpc_endpoint_destroy(t->ep);
+ t->ep = NULL;
+ gpr_cv_broadcast(&t->cv);
+ unref_transport(t); /* safe because we'll still have the ref for write */
+ }
+ unlock(t);
+
+ unref_transport(t);
+}
+
+static void finish_write(void *tp, grpc_endpoint_cb_status error) {
+ transport *t = tp;
+ finish_write_common(t, error == GRPC_ENDPOINT_CB_OK);
+}
+
+static void perform_write(transport *t, grpc_endpoint *ep) {
+ finalize_outbuf(t);
+
+ GPR_ASSERT(t->outbuf.count > 0);
+
+ switch (grpc_endpoint_write(ep, t->outbuf.slices, t->outbuf.count,
+ finish_write, t)) {
+ case GRPC_ENDPOINT_WRITE_DONE:
+ finish_write_common(t, 1);
+ break;
+ case GRPC_ENDPOINT_WRITE_ERROR:
+ finish_write_common(t, 0);
+ break;
+ case GRPC_ENDPOINT_WRITE_PENDING:
+ break;
+ }
}
static void maybe_start_some_streams(transport *t) {
@@ -901,19 +926,14 @@ static void send_batch(grpc_transport *gt, grpc_stream *gs, grpc_stream_op *ops,
lock(t);
if (is_last) {
- s->write_closed = 1;
+ s->queued_write_closed = 1;
}
if (!s->cancelled) {
grpc_sopb_append(&s->outgoing_sopb, ops, ops_count);
- if (is_last && s->outgoing_sopb.nops == 0) {
- if (s->id != 0) {
- gpr_slice_buffer_add(&t->qbuf,
- grpc_chttp2_data_frame_create_empty_close(s->id));
- }
- } else if (s->id == 0) {
+ if (s->id == 0) {
stream_list_join(t, s, WAITING_FOR_CONCURRENCY);
maybe_start_some_streams(t);
- } else if (s->outgoing_window) {
+ } else {
stream_list_join(t, s, WRITABLE);
}
} else {
@@ -967,12 +987,22 @@ static void send_ping(grpc_transport *gt, void (*cb)(void *user_data),
* INPUT PROCESSING
*/
+static void finalize_cancellations(transport *t) {
+ stream *s;
+
+ while ((s = stream_list_remove_head(t, CANCELLED))) {
+ s->read_closed = 1;
+ s->sent_write_closed = 1;
+ stream_list_join(t, s, PENDING_CALLBACKS);
+ }
+}
+
static void cancel_stream_inner(transport *t, stream *s, gpr_uint32 id,
grpc_status_code local_status,
grpc_chttp2_error_code error_code,
int send_rst) {
- char buffer[32];
int had_outgoing;
+ char buffer[32];
if (s) {
/* clear out any unreported input & output: nobody cares anymore */
@@ -981,10 +1011,9 @@ static void cancel_stream_inner(transport *t, stream *s, gpr_uint32 id,
grpc_sopb_reset(&s->outgoing_sopb);
if (s->cancelled) {
send_rst = 0;
- } else if (!s->read_closed || !s->write_closed || had_outgoing) {
+ } else if (!s->read_closed || !s->sent_write_closed || had_outgoing) {
s->cancelled = 1;
- s->read_closed = 1;
- s->write_closed = 1;
+ stream_list_join(t, s, CANCELLED);
sprintf(buffer, "%d", local_status);
grpc_sopb_add_metadata(
@@ -1667,8 +1696,7 @@ static int prepare_callbacks(transport *t) {
s->parser.incoming_sopb = s->callback_sopb;
s->callback_sopb = temp_sopb;
- s->callback_state = compute_state(
- s->write_closed && s->outgoing_sopb.nops == 0, s->read_closed);
+ s->callback_state = compute_state(s->sent_write_closed, s->read_closed);
if (s->callback_state == GRPC_STREAM_CLOSED) {
remove_from_stream_map(t, s);
if (s->published_close) {
diff --git a/src/core/transport/chttp2_transport.h b/src/core/transport/chttp2_transport.h
index dd4419b98d..e12357ff5e 100644
--- a/src/core/transport/chttp2_transport.h
+++ b/src/core/transport/chttp2_transport.h
@@ -44,4 +44,4 @@ void grpc_create_chttp2_transport(grpc_transport_setup_callback setup,
size_t nslices, grpc_mdctx *metadata_context,
int is_client);
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_TRANSPORT_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_TRANSPORT_H__ */
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
index 6c6dee5efd..943e65a981 100644
--- a/src/core/transport/metadata.h
+++ b/src/core/transport/metadata.h
@@ -136,4 +136,4 @@ const char *grpc_mdstr_as_c_string(grpc_mdstr *s);
#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
-#endif /* __GRPC_INTERNAL_TRANSPORT_METADATA_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_METADATA_H__ */
diff --git a/src/core/transport/stream_op.h b/src/core/transport/stream_op.h
index be60bc2da6..20d609133f 100644
--- a/src/core/transport/stream_op.h
+++ b/src/core/transport/stream_op.h
@@ -125,4 +125,4 @@ void grpc_sopb_add_flow_ctl_cb(grpc_stream_op_buffer *sopb,
void grpc_sopb_append(grpc_stream_op_buffer *sopb, grpc_stream_op *ops,
size_t nops);
-#endif /* __GRPC_INTERNAL_TRANSPORT_STREAM_OP_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_STREAM_OP_H__ */
diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h
index 00dacbf5b9..af12f4e700 100644
--- a/src/core/transport/transport.h
+++ b/src/core/transport/transport.h
@@ -254,4 +254,4 @@ void grpc_transport_setup_initiate(grpc_transport_setup *setup);
used as a destruction call by setup). */
void grpc_transport_setup_cancel(grpc_transport_setup *setup);
-#endif /* __GRPC_INTERNAL_TRANSPORT_TRANSPORT_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_TRANSPORT_H__ */
diff --git a/src/core/transport/transport_impl.h b/src/core/transport/transport_impl.h
index 9f497b9cba..31e80d36ed 100644
--- a/src/core/transport/transport_impl.h
+++ b/src/core/transport/transport_impl.h
@@ -84,4 +84,4 @@ struct grpc_transport {
const grpc_transport_vtable *vtable;
};
-#endif /* __GRPC_INTERNAL_TRANSPORT_TRANSPORT_IMPL_H__ */
+#endif /* __GRPC_INTERNAL_TRANSPORT_TRANSPORT_IMPL_H__ */
diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c
index 7807e71949..63d0e1f788 100644
--- a/src/core/tsi/fake_transport_security.c
+++ b/src/core/tsi/fake_transport_security.c
@@ -83,7 +83,6 @@ typedef struct {
uint32_t max_frame_size;
} tsi_fake_frame_protector;
-
/* --- Utils. ---*/
static const char* tsi_fake_handshake_message_strings[] = {
@@ -120,7 +119,7 @@ static void store32_little_endian(uint32_t value, unsigned char* buf) {
buf[3] = (unsigned char)(value >> 24) & 0xFF;
buf[2] = (unsigned char)(value >> 16) & 0xFF;
buf[1] = (unsigned char)(value >> 8) & 0xFF;
- buf[0] = (unsigned char)(value) & 0xFF;
+ buf[0] = (unsigned char)(value)&0xFF;
}
static void tsi_fake_frame_reset(tsi_fake_frame* frame, int needs_draining) {
@@ -246,8 +245,8 @@ static tsi_result fake_protector_protect(
/* Try to drain first. */
if (frame->needs_draining) {
drained_size = saved_output_size - *num_bytes_written;
- result = drain_frame_to_bytes(protected_output_frames,
- &drained_size, frame);
+ result =
+ drain_frame_to_bytes(protected_output_frames, &drained_size, frame);
*num_bytes_written += drained_size;
protected_output_frames += drained_size;
if (result != TSI_OK) {
@@ -273,8 +272,8 @@ static tsi_result fake_protector_protect(
return result;
}
}
- result = fill_frame_from_bytes(unprotected_bytes, unprotected_bytes_size,
- frame);
+ result =
+ fill_frame_from_bytes(unprotected_bytes, unprotected_bytes_size, frame);
if (result != TSI_OK) {
if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
return result;
@@ -301,7 +300,7 @@ static tsi_result fake_protector_protect_flush(
frame->size = frame->offset;
frame->offset = 0;
frame->needs_draining = 1;
- store32_little_endian(frame->size, frame->data); /* Overwrite header. */
+ store32_little_endian(frame->size, frame->data); /* Overwrite header. */
}
result = drain_frame_to_bytes(protected_output_frames,
protected_output_frames_size, frame);
@@ -327,8 +326,7 @@ static tsi_result fake_protector_unprotect(
/* Go past the header if needed. */
if (frame->offset == 0) frame->offset = TSI_FAKE_FRAME_HEADER_SIZE;
drained_size = saved_output_size - *num_bytes_written;
- result = drain_frame_to_bytes(unprotected_bytes, &drained_size,
- frame);
+ result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame);
unprotected_bytes += drained_size;
*num_bytes_written += drained_size;
if (result != TSI_OK) {
@@ -352,7 +350,7 @@ static tsi_result fake_protector_unprotect(
/* Try to drain again. */
if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
if (frame->offset != 0) return TSI_INTERNAL_ERROR;
- frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; /* Go past the header. */
+ frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; /* Go past the header. */
drained_size = saved_output_size - *num_bytes_written;
result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame);
*num_bytes_written += drained_size;
@@ -481,10 +479,8 @@ static void fake_handshaker_destroy(tsi_handshaker* self) {
static const tsi_handshaker_vtable handshaker_vtable = {
fake_handshaker_get_bytes_to_send_to_peer,
- fake_handshaker_process_bytes_from_peer,
- fake_handshaker_get_result,
- fake_handshaker_extract_peer,
- fake_handshaker_create_frame_protector,
+ fake_handshaker_process_bytes_from_peer, fake_handshaker_get_result,
+ fake_handshaker_extract_peer, fake_handshaker_create_frame_protector,
fake_handshaker_destroy,
};
diff --git a/src/core/tsi/fake_transport_security.h b/src/core/tsi/fake_transport_security.h
index 075d51871b..a62fe81c09 100644
--- a/src/core/tsi/fake_transport_security.h
+++ b/src/core/tsi/fake_transport_security.h
@@ -50,7 +50,6 @@ extern "C" {
cleartext data for the protector. */
tsi_handshaker* tsi_create_fake_handshaker(int is_client);
-
/* Creates a protector directly without going through the handshake phase. */
tsi_frame_protector* tsi_create_fake_protector(
uint32_t* max_protected_frame_size);
@@ -59,4 +58,4 @@ tsi_frame_protector* tsi_create_fake_protector(
}
#endif
-#endif /* __FAKE_TRANSPORT_SECURITY_H_ */
+#endif /* __FAKE_TRANSPORT_SECURITY_H_ */
diff --git a/src/core/tsi/fake_transport_security_test.cc b/src/core/tsi/fake_transport_security_test.cc
deleted file mode 100644
index 0ae88e0c9a..0000000000
--- a/src/core/tsi/fake_transport_security_test.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- *
- * Copyright 2014, 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 "src/core/tsi/fake_transport_security.h"
-
-#include "src/core/tsi/transport_security_test_lib.h"
-#include <gtest/gtest.h>
-#include "util/random/permute-inl.h"
-
-namespace {
-
-void CheckStringPeerProperty(const tsi_peer& peer, int property_index,
- const char* expected_name,
- const char* expected_value) {
- EXPECT_LT(property_index, peer.property_count);
- const tsi_peer_property* property = &peer.properties[property_index];
- EXPECT_EQ(TSI_PEER_PROPERTY_TYPE_STRING, property->type);
- EXPECT_EQ(string(expected_name), string(property->name));
- EXPECT_EQ(string(expected_value),
- string(property->value.string.data, property->value.string.length));
-}
-
-class FakeTransportSecurityTest : public tsi::test::TransportSecurityTest {
- protected:
- void SetupHandshakers() override {
- client_handshaker_.reset(tsi_create_fake_handshaker(1));
- server_handshaker_.reset(tsi_create_fake_handshaker(0));
- }
-
- void CheckPeer(tsi_handshaker* handshaker) {
- tsi_peer peer;
- EXPECT_EQ(TSI_OK, tsi_handshaker_extract_peer(handshaker, &peer));
- EXPECT_EQ(1, peer.property_count);
- CheckStringPeerProperty(peer, 0, TSI_CERTIFICATE_TYPE_PEER_PROPERTY,
- TSI_FAKE_CERTIFICATE_TYPE);
- tsi_peer_destruct(&peer);
- }
-
- void CheckHandshakeResults() override {
- CheckPeer(client_handshaker_.get());
- CheckPeer(server_handshaker_.get());
- }
-
- const tsi::test::TestConfig* config() {
- return &config_;
- }
-
- tsi::test::TestConfig config_;
-};
-
-TEST_F(FakeTransportSecurityTest, Handshake) {
- PerformHandshake();
-}
-
-TEST_F(FakeTransportSecurityTest, HandshakeSmallBuffer) {
- config_.handshake_buffer_size = 3;
- PerformHandshake();
-}
-TEST_F(FakeTransportSecurityTest, PingPong) {
- PingPong();
-}
-
-TEST_F(FakeTransportSecurityTest, RoundTrip) {
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(FakeTransportSecurityTest, RoundTripSmallMessageBuffer) {
- config_.message_buffer_allocated_size = 42;
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(FakeTransportSecurityTest, RoundTripSmallProtectedBufferSize) {
- config_.protected_buffer_size = 37;
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(FakeTransportSecurityTest, RoundTripSmallReadBufferSize) {
- config_.read_buffer_allocated_size = 41;
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(FakeTransportSecurityTest, RoundTripSmallClientFrames) {
- config_.set_client_max_output_protected_frame_size(39);
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(FakeTransportSecurityTest, RoundTripSmallServerFrames) {
- config_.set_server_max_output_protected_frame_size(43);
- config_.client_message = small_message_;
- config_.server_message = big_message_;
- DoRoundTrip();
-}
-
-TEST_F(FakeTransportSecurityTest, RoundTripOddBufferSizes) {
- int odd_sizes[] = {33, 67, 135, 271, 523};
- RandomPermutation<int> permute(odd_sizes, arraysize(odd_sizes),
- random_.get());
- permute.Permute();
- LOG(ERROR) << odd_sizes[0] << "\t" << odd_sizes[1] << "\t" << odd_sizes[2]
- << "\t" << odd_sizes[3] << "\t" << odd_sizes[4];
- config_.message_buffer_allocated_size = odd_sizes[0];
- config_.protected_buffer_size = odd_sizes[1];
- config_.read_buffer_allocated_size = odd_sizes[2];
- config_.set_client_max_output_protected_frame_size(odd_sizes[3]);
- config_.set_server_max_output_protected_frame_size(odd_sizes[4]);
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-} // namespace
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index b9e48e7373..c98071a937 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -54,7 +54,6 @@
* SSL structure. This is what we would ultimately want though... */
#define TSI_SSL_MAX_PROTECTION_OVERHEAD 100
-
/* --- Structure definitions. ---*/
struct tsi_ssl_handshaker_factory {
@@ -100,7 +99,6 @@ typedef struct {
uint32_t buffer_offset;
} tsi_ssl_frame_protector;
-
/* --- Library Initialization. ---*/
static gpr_once init_openssl_once = GPR_ONCE_INIT;
@@ -269,7 +267,7 @@ static tsi_result peer_from_x509(X509* cert, int include_certificate_type,
tsi_peer* peer) {
/* TODO(jboeuf): Maybe add more properties. */
uint32_t property_count = include_certificate_type ? 3 : 2;
- tsi_result result = tsi_construct_peer(property_count, peer);
+ tsi_result result = tsi_construct_peer(property_count, peer);
if (result != TSI_OK) return result;
do {
result = peer_property_from_x509_common_name(cert, &peer->properties[0]);
@@ -299,12 +297,10 @@ static void log_ssl_error_stack(void) {
}
}
-
/* Performs an SSL_read and handle errors. */
static tsi_result do_ssl_read(SSL* ssl, unsigned char* unprotected_bytes,
uint32_t* unprotected_bytes_size) {
- int read_from_ssl = SSL_read(ssl, unprotected_bytes,
- *unprotected_bytes_size);
+ int read_from_ssl = SSL_read(ssl, unprotected_bytes, *unprotected_bytes_size);
if (read_from_ssl == 0) {
gpr_log(GPR_ERROR, "SSL_read returned 0 unexpectedly.");
return TSI_INTERNAL_ERROR;
@@ -378,7 +374,7 @@ static tsi_result ssl_ctx_use_certificate_chain(
X509* certificate_authority = PEM_read_bio_X509(pem, NULL, NULL, "");
if (certificate_authority == NULL) {
ERR_clear_error();
- break; /* Done reading. */
+ break; /* Done reading. */
}
if (!SSL_CTX_add_extra_chain_cert(context, certificate_authority)) {
X509_free(certificate_authority);
@@ -423,8 +419,8 @@ static tsi_result ssl_ctx_use_private_key(SSL_CTX* context,
/* Loads in-memory PEM verification certs into the SSL context and optionally
returns the verification cert names (root_names can be NULL). */
static tsi_result ssl_ctx_load_verification_certs(
- SSL_CTX* context, const unsigned char* pem_roots,
- uint32_t pem_roots_size, STACK_OF(X509_NAME)** root_names) {
+ SSL_CTX* context, const unsigned char* pem_roots, uint32_t pem_roots_size,
+ STACK_OF(X509_NAME) * *root_names) {
tsi_result result = TSI_OK;
uint32_t num_roots = 0;
X509* root = NULL;
@@ -442,7 +438,7 @@ static tsi_result ssl_ctx_load_verification_certs(
root = PEM_read_bio_X509_AUX(pem, NULL, NULL, "");
if (root == NULL) {
ERR_clear_error();
- break; /* We're at the end of stream. */
+ break; /* We're at the end of stream. */
}
if (root_names != NULL) {
root_name = X509_get_subject_name(root);
@@ -485,13 +481,11 @@ static tsi_result ssl_ctx_load_verification_certs(
return result;
}
-
/* Populates the SSL context with a private key and a cert chain, and sets the
cipher list and the ephemeral ECDH key. */
static tsi_result populate_ssl_context(
SSL_CTX* context, const unsigned char* pem_private_key,
- uint32_t pem_private_key_size,
- const unsigned char* pem_certificate_chain,
+ uint32_t pem_private_key_size, const unsigned char* pem_certificate_chain,
uint32_t pem_certificate_chain_size, const char* cipher_list) {
tsi_result result = TSI_OK;
if (pem_certificate_chain != NULL) {
@@ -532,12 +526,12 @@ static tsi_result extract_x509_subject_names_from_pem_cert(
tsi_result result = TSI_OK;
X509* cert = NULL;
BIO* pem = BIO_new_mem_buf((void*)pem_cert, pem_cert_size);
- if (pem == NULL) return TSI_OUT_OF_RESOURCES;
+ if (pem == NULL) return TSI_OUT_OF_RESOURCES;
cert = PEM_read_bio_X509(pem, NULL, NULL, "");
if (cert == NULL) {
- gpr_log(GPR_ERROR, "Invalid certificate");
- result = TSI_INVALID_ARGUMENT;
+ gpr_log(GPR_ERROR, "Invalid certificate");
+ result = TSI_INVALID_ARGUMENT;
} else {
result = peer_from_x509(cert, 0, peer);
}
@@ -581,8 +575,7 @@ static tsi_result build_alpn_protocol_name_list(
static tsi_result ssl_protector_protect(
tsi_frame_protector* self, const unsigned char* unprotected_bytes,
- uint32_t* unprotected_bytes_size,
- unsigned char* protected_output_frames,
+ uint32_t* unprotected_bytes_size, unsigned char* protected_output_frames,
uint32_t* protected_output_frames_size) {
tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self;
int read_from_ssl;
@@ -634,8 +627,7 @@ static tsi_result ssl_protector_protect(
static tsi_result ssl_protector_protect_flush(
tsi_frame_protector* self, unsigned char* protected_output_frames,
- uint32_t* protected_output_frames_size,
- uint32_t* still_pending_size) {
+ uint32_t* protected_output_frames_size, uint32_t* still_pending_size) {
tsi_result result = TSI_OK;
tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self;
int read_from_ssl = 0;
@@ -662,8 +654,7 @@ static tsi_result ssl_protector_protect_flush(
static tsi_result ssl_protector_unprotect(
tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
- uint32_t* protected_frames_bytes_size,
- unsigned char* unprotected_bytes,
+ uint32_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
uint32_t* unprotected_bytes_size) {
tsi_result result = TSI_OK;
int written_into_ssl = 0;
@@ -673,7 +664,7 @@ static tsi_result ssl_protector_unprotect(
/* First, try to read remaining data from ssl. */
result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size);
- if (result != TSI_OK) return result;
+ if (result != TSI_OK) return result;
if (*unprotected_bytes_size == output_bytes_size) {
/* We have read everything we could and cannot process any more input. */
*protected_frames_bytes_size = 0;
@@ -684,8 +675,8 @@ static tsi_result ssl_protector_unprotect(
*unprotected_bytes_size = output_bytes_size - output_bytes_offset;
/* Then, try to write some data to ssl. */
- written_into_ssl = BIO_write(
- impl->into_ssl, protected_frames_bytes, *protected_frames_bytes_size);
+ written_into_ssl = BIO_write(impl->into_ssl, protected_frames_bytes,
+ *protected_frames_bytes_size);
if (written_into_ssl < 0) {
gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d",
written_into_ssl);
@@ -710,13 +701,10 @@ static void ssl_protector_destroy(tsi_frame_protector* self) {
}
static const tsi_frame_protector_vtable frame_protector_vtable = {
- ssl_protector_protect,
- ssl_protector_protect_flush,
- ssl_protector_unprotect,
+ ssl_protector_protect, ssl_protector_protect_flush, ssl_protector_unprotect,
ssl_protector_destroy,
};
-
/* --- tsi_handshaker methods implementation. ---*/
static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(
@@ -751,8 +739,7 @@ static tsi_result ssl_handshaker_get_result(tsi_handshaker* self) {
}
static tsi_result ssl_handshaker_process_bytes_from_peer(
- tsi_handshaker* self, const unsigned char* bytes,
- uint32_t* bytes_size) {
+ tsi_handshaker* self, const unsigned char* bytes, uint32_t* bytes_size) {
tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self;
int bytes_written_into_ssl_size = 0;
if (bytes == NULL || bytes_size == 0 || *bytes_size > INT_MAX) {
@@ -884,14 +871,11 @@ static void ssl_handshaker_destroy(tsi_handshaker* self) {
static const tsi_handshaker_vtable handshaker_vtable = {
ssl_handshaker_get_bytes_to_send_to_peer,
- ssl_handshaker_process_bytes_from_peer,
- ssl_handshaker_get_result,
- ssl_handshaker_extract_peer,
- ssl_handshaker_create_frame_protector,
+ ssl_handshaker_process_bytes_from_peer, ssl_handshaker_get_result,
+ ssl_handshaker_extract_peer, ssl_handshaker_create_frame_protector,
ssl_handshaker_destroy,
};
-
/* --- tsi_ssl_handshaker_factory common methods. --- */
tsi_result tsi_ssl_handshaker_factory_create_handshaker(
@@ -971,7 +955,6 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
return TSI_OK;
}
-
/* --- tsi_ssl__client_handshaker_factory methods implementation. --- */
static tsi_result ssl_client_handshaker_factory_create_handshaker(
@@ -991,7 +974,6 @@ static void ssl_client_handshaker_factory_destroy(
free(impl);
}
-
/* --- tsi_ssl_server_handshaker_factory methods implementation. --- */
static tsi_result ssl_server_handshaker_factory_create_handshaker(
@@ -1031,19 +1013,19 @@ static int does_entry_match_name(const char* entry, uint32_t entry_length,
const char* name_subdomain = NULL;
if (entry_length == 0) return 0;
if (!strncmp(name, entry, entry_length) && (strlen(name) == entry_length)) {
- return 1; /* Perfect match. */
+ return 1; /* Perfect match. */
}
if (entry[0] != '*') return 0;
/* Wildchar subdomain matching. */
- if (entry_length < 3 || entry[1] != '.') { /* At least *.x */
+ if (entry_length < 3 || entry[1] != '.') { /* At least *.x */
gpr_log(GPR_ERROR, "Invalid wildchar entry.");
return 0;
}
name_subdomain = strchr(name, '.');
if (name_subdomain == NULL || strlen(name_subdomain) < 2) return 0;
- name_subdomain++; /* Starts after the dot. */
- entry += 2; /* Remove *. */
+ name_subdomain++; /* Starts after the dot. */
+ entry += 2; /* Remove *. */
entry_length -= 2;
return (!strncmp(entry, name_subdomain, entry_length) &&
(strlen(name_subdomain) == entry_length));
@@ -1095,7 +1077,6 @@ static int server_handshaker_factory_alpn_callback(
return SSL_TLSEXT_ERR_NOACK;
}
-
/* --- tsi_ssl_handshaker_factory constructors. --- */
tsi_result tsi_create_ssl_client_handshaker_factory(
@@ -1277,10 +1258,8 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) {
uint32_t i = 0;
const tsi_peer_property* property = tsi_peer_get_property_by_name(
peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
- if (property == NULL ||
- property->type != TSI_PEER_PROPERTY_TYPE_STRING) {
- gpr_log(GPR_ERROR,
- "Invalid x509 subject common name property.");
+ if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_STRING) {
+ gpr_log(GPR_ERROR, "Invalid x509 subject common name property.");
return 0;
}
if (does_entry_match_name(property->value.string.data,
@@ -1291,8 +1270,7 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) {
property = tsi_peer_get_property_by_name(
peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY);
if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_LIST) {
- gpr_log(GPR_ERROR,
- "Invalid x509 subject alternative names property.");
+ gpr_log(GPR_ERROR, "Invalid x509 subject alternative names property.");
return 0;
}
@@ -1308,5 +1286,5 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) {
return 1;
}
}
- return 0; /* Not found. */
+ return 0; /* Not found. */
}
diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
index 2ed3ed861b..de2b1df7bf 100644
--- a/src/core/tsi/ssl_transport_security.h
+++ b/src/core/tsi/ssl_transport_security.h
@@ -43,6 +43,17 @@ extern "C" {
/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */
#define TSI_X509_CERTIFICATE_TYPE "X509"
+/* This property is of type TSI_PEER_PROPERTY_STRING. */
+#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name"
+
+/* This property is of type TSI_PEER_PROPERTY_LIST and the children contain
+ unnamed (name == NULL) properties of type TSI_PEER_PROPERTY_STRING. */
+#define TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY \
+ "x509_subject_alternative_names"
+
+/* This property is of type TSI_PEER_PROPERTY_STRING. */
+#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol"
+
/* --- tsi_ssl_handshaker_factory object ---
This object creates tsi_handshaker objects implemented in terms of the
@@ -151,9 +162,8 @@ void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory* self);
/* Util that checks that an ssl peer matches a specific name. */
int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name);
-
#ifdef __cplusplus
}
#endif
-#endif /* __SSL_TRANSPORT_SECURITY_H_ */
+#endif /* __SSL_TRANSPORT_SECURITY_H_ */
diff --git a/src/core/tsi/ssl_transport_security_test.cc b/src/core/tsi/ssl_transport_security_test.cc
deleted file mode 100644
index a759403126..0000000000
--- a/src/core/tsi/ssl_transport_security_test.cc
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- *
- * Copyright 2014, 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 <memory>
-
-#include "base/commandlineflags.h"
-#include "file/base/helpers.h"
-#include "file/base/options.pb.h"
-#include "file/base/path.h"
-#include "src/core/tsi/transport_security_test_lib.h"
-#include "src/core/tsi/ssl_transport_security.h"
-#include "util/random/permute-inl.h"
-
-namespace {
-
-const char kTestCredsDir[] =
- "/internal/tsi/test_creds/";
-
-enum AlpnMode {
- NO_ALPN,
- ALPN_CLIENT_NO_SERVER,
- ALPN_SERVER_NO_CLIENT,
- ALPN_CLIENT_SERVER_OK,
- ALPN_CLIENT_SERVER_MISMATCH
-};
-
-class SslTestConfig : public tsi::test::TestConfig {
- public:
- SslTestConfig()
- : do_client_authentication(false),
- subject_name_indication(nullptr),
- use_bad_client_cert(false),
- use_bad_server_cert(false),
- alpn_mode(NO_ALPN) {}
- bool do_client_authentication;
- const char* subject_name_indication;
- bool use_bad_client_cert;
- bool use_bad_server_cert;
- AlpnMode alpn_mode;
-};
-
-struct TsiSslHandshakerFactoryDeleter {
- inline void operator()(tsi_ssl_handshaker_factory* ptr) {
- tsi_ssl_handshaker_factory_destroy(ptr);
- }
-};
-typedef std::unique_ptr<tsi_ssl_handshaker_factory,
- TsiSslHandshakerFactoryDeleter>
- TsiSslHandshakerFactoryUniquePtr;
-
-class SslTransportSecurityTest : public tsi::test::TransportSecurityTest {
- protected:
- void CheckSubjectAltName(const tsi_peer_property& property,
- const string& expected_subject_alt_name) {
- EXPECT_EQ(property.type, TSI_PEER_PROPERTY_TYPE_STRING);
- EXPECT_EQ(property.name, nullptr);
- EXPECT_EQ(
- string(property.value.string.data, property.value.string.length),
- expected_subject_alt_name);
- }
-
- const tsi_peer_property* CheckBasicAuthenticatedPeerAndGetCommonName(
- const tsi_peer* peer) {
- const tsi_peer_property* property =
- tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY);
- EXPECT_NE(property, nullptr);
- EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_STRING);
- EXPECT_EQ(
- string(property->value.string.data, property->value.string.length),
- string(TSI_X509_CERTIFICATE_TYPE));
- property = tsi_peer_get_property_by_name(
- peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
- EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_STRING);
- return property;
- }
-
- void CheckServer0Peer(tsi_peer* peer) {
- const tsi_peer_property* property =
- CheckBasicAuthenticatedPeerAndGetCommonName(peer);
- EXPECT_EQ(
- string(property->value.string.data, property->value.string.length),
- string("*.test.google.com.au"));
- property = tsi_peer_get_property_by_name(
- peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY);
- EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_LIST);
- EXPECT_EQ(property->value.list.child_count, 0);
- EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au"));
- EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au"));
- EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "bar.test.google.blah"));
- EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au"));
- EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "test.google.com.au"));
- tsi_peer_destruct(peer);
- }
-
- void CheckServer1Peer(tsi_peer* peer) {
- const tsi_peer_property* property =
- CheckBasicAuthenticatedPeerAndGetCommonName(peer);
- EXPECT_EQ(
- string(property->value.string.data, property->value.string.length),
- string("*.test.google.com"));
- property = tsi_peer_get_property_by_name(
- peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY);
- EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_LIST);
- EXPECT_EQ(property->value.list.child_count, 3);
- CheckSubjectAltName(property->value.list.children[0], "*.test.google.fr");
- CheckSubjectAltName(property->value.list.children[1],
- "waterzooi.test.google.be");
- CheckSubjectAltName(property->value.list.children[2], "*.test.youtube.com");
- EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.google.com"));
- EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "bar.test.google.fr"));
- EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "waterzooi.test.google.be"));
- EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.youtube.com"));
- EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "bar.foo.test.google.com"));
- EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "test.google.fr"));
- EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "tartines.test.google.be"));
- EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "tartines.youtube.com"));
- tsi_peer_destruct(peer);
- }
-
- void CheckClientPeer(tsi_peer* peer, bool is_authenticated) {
- if (!is_authenticated) {
- EXPECT_EQ(peer->property_count,
- config_.alpn_mode == ALPN_CLIENT_SERVER_OK ? 1 : 0);
- } else {
- const tsi_peer_property* property =
- CheckBasicAuthenticatedPeerAndGetCommonName(peer);
- EXPECT_EQ(
- string(property->value.string.data, property->value.string.length),
- string("testclient"));
- }
- tsi_peer_destruct(peer);
- }
-
- void SetupHandshakers() override {
- tsi_ssl_handshaker_factory* client_handshaker_factory;
- const unsigned char* client_cert = NULL;
- unsigned int client_cert_size = 0;
- const unsigned char* client_key = NULL;
- unsigned int client_key_size = 0;
- if (config_.do_client_authentication) {
- if (config_.use_bad_client_cert) {
- client_cert =
- reinterpret_cast<const unsigned char*>(badclient_cert_.data());
- client_cert_size = badclient_cert_.size();
- client_key =
- reinterpret_cast<const unsigned char*>(badclient_key_.data());
- client_key_size = badclient_key_.size();
- } else {
- client_cert =
- reinterpret_cast<const unsigned char*>(client_cert_.data());
- client_cert_size = client_cert_.size();
- client_key = reinterpret_cast<const unsigned char*>(client_key_.data());
- client_key_size = client_key_.size();
- }
- }
- const unsigned char** client_alpn_protocols(nullptr);
- const unsigned char* client_alpn_protocols_lengths(nullptr);
- uint16_t num_client_alpn_protocols = 0;
- if (config_.alpn_mode == ALPN_CLIENT_NO_SERVER ||
- config_.alpn_mode == ALPN_CLIENT_SERVER_OK ||
- config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
- client_alpn_protocols =
- reinterpret_cast<const unsigned char**>(&client_alpn_protocols_[0]);
- client_alpn_protocols_lengths = &client_alpn_protocols_lengths_[0];
- num_client_alpn_protocols = client_alpn_protocols_.size();
- }
-
- EXPECT_EQ(tsi_create_ssl_client_handshaker_factory(
- client_key, client_key_size, client_cert, client_cert_size,
- reinterpret_cast<const unsigned char*>(root_certs_.data()),
- root_certs_.size(), NULL, client_alpn_protocols,
- client_alpn_protocols_lengths, num_client_alpn_protocols,
- &client_handshaker_factory),
- TSI_OK);
- client_handshaker_factory_.reset(client_handshaker_factory);
-
- const unsigned char** server_alpn_protocols(nullptr);
- const unsigned char* server_alpn_protocols_lengths(nullptr);
- uint16_t num_server_alpn_protocols = 0;
- if (config_.alpn_mode == ALPN_SERVER_NO_CLIENT ||
- config_.alpn_mode == ALPN_CLIENT_SERVER_OK ||
- config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
- server_alpn_protocols =
- reinterpret_cast<const unsigned char**>(&server_alpn_protocols_[0]);
- server_alpn_protocols_lengths = &server_alpn_protocols_lengths_[0];
- num_server_alpn_protocols = server_alpn_protocols_.size();
- if (config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
- // Remove the last element that is common.
- num_server_alpn_protocols--;
- }
- }
- tsi_ssl_handshaker_factory* server_handshaker_factory;
- EXPECT_EQ(
- tsi_create_ssl_server_handshaker_factory(
- config_.use_bad_server_cert ? &badserver_keys_[0]
- : &server_keys_[0],
- config_.use_bad_server_cert ? &badserver_keys_sizes_[0]
- : &server_keys_sizes_[0],
- config_.use_bad_server_cert ? &badserver_certs_[0]
- : &server_certs_[0],
- config_.use_bad_server_cert ? &badserver_certs_sizes_[0]
- : &server_certs_sizes_[0],
- config_.use_bad_server_cert ? badserver_keys_.size()
- : server_keys_.size(),
- config_.do_client_authentication
- ? reinterpret_cast<const unsigned char*>(root_certs_.data())
- : NULL,
- config_.do_client_authentication ? root_certs_.size() : 0, NULL,
- server_alpn_protocols, server_alpn_protocols_lengths,
- num_server_alpn_protocols, &server_handshaker_factory),
- TSI_OK);
- server_handshaker_factory_.reset(server_handshaker_factory);
-
- tsi_handshaker* client_handshaker;
- EXPECT_EQ(tsi_ssl_handshaker_factory_create_handshaker(
- client_handshaker_factory, config_.subject_name_indication,
- &client_handshaker),
- TSI_OK);
- client_handshaker_.reset(client_handshaker);
-
- tsi_handshaker* server_handshaker;
- EXPECT_EQ(tsi_ssl_handshaker_factory_create_handshaker(
- server_handshaker_factory, NULL, &server_handshaker),
- TSI_OK);
- server_handshaker_.reset(server_handshaker);
- }
-
- void CheckAlpn(const tsi_peer* peer) {
- const tsi_peer_property* alpn_property =
- tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
- if (config_.alpn_mode != ALPN_CLIENT_SERVER_OK) {
- EXPECT_EQ(nullptr, alpn_property);
- } else {
- EXPECT_NE(nullptr, alpn_property);
- EXPECT_EQ(TSI_PEER_PROPERTY_TYPE_STRING, alpn_property->type);
- string expected_match("baz");
- EXPECT_EQ(expected_match, string(alpn_property->value.string.data,
- alpn_property->value.string.length));
- }
- }
-
- void CheckHandshakeResults() override {
- tsi_peer peer;
-
- bool expect_success =
- !(config_.use_bad_server_cert ||
- (config_.use_bad_client_cert && config_.do_client_authentication));
- tsi_result result = tsi_handshaker_get_result(client_handshaker_.get());
- EXPECT_NE(result, TSI_HANDSHAKE_IN_PROGRESS);
- if (expect_success) {
- EXPECT_EQ(result, TSI_OK);
- EXPECT_EQ(tsi_handshaker_extract_peer(client_handshaker_.get(), &peer),
- TSI_OK);
- CheckAlpn(&peer);
- // TODO(jboeuf): This is a bit fragile. Maybe revisit.
- if (config_.subject_name_indication != nullptr) {
- CheckServer1Peer(&peer);
- } else {
- CheckServer0Peer(&peer);
- }
- } else {
- EXPECT_NE(result, TSI_OK);
- EXPECT_NE(tsi_handshaker_extract_peer(client_handshaker_.get(), &peer),
- TSI_OK);
- }
-
- result = tsi_handshaker_get_result(server_handshaker_.get());
- EXPECT_NE(result, TSI_HANDSHAKE_IN_PROGRESS);
- if (expect_success) {
- EXPECT_EQ(result, TSI_OK);
- EXPECT_EQ(tsi_handshaker_extract_peer(server_handshaker_.get(), &peer),
- TSI_OK);
- CheckAlpn(&peer);
- CheckClientPeer(&peer, config_.do_client_authentication);
- } else {
- EXPECT_NE(result, TSI_OK);
- EXPECT_NE(tsi_handshaker_extract_peer(server_handshaker_.get(), &peer),
- TSI_OK);
- }
- }
-
- const tsi::test::TestConfig* config() override {
- return &config_;
- }
-
- SslTransportSecurityTest()
- : client_alpn_protocols_({"foo", "toto", "baz"}),
- server_alpn_protocols_({"boooo", "far", "baz"}),
- client_alpn_protocols_lengths_({3, 4, 3}),
- server_alpn_protocols_lengths_({5, 3, 3}) {
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badserver.key"),
- &badserver_key_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badserver.pem"),
- &badserver_cert_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badclient.key"),
- &badclient_key_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badclient.pem"),
- &badclient_cert_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server0.key"),
- &server0_key_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server0.pem"),
- &server0_cert_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server1.key"),
- &server1_key_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server1.pem"),
- &server1_cert_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "client.key"),
- &client_key_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "client.pem"),
- &client_cert_, file::Options()));
- CHECK_OK(file::GetContents(
- file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "ca.pem"),
- &root_certs_, file::Options()));
- badserver_keys_.push_back(
- reinterpret_cast<const unsigned char*>(badserver_key_.data()));
- badserver_certs_.push_back(
- reinterpret_cast<const unsigned char*>(badserver_cert_.data()));
- server_keys_.push_back(
- reinterpret_cast<const unsigned char*>(server0_key_.data()));
- server_keys_.push_back(
- reinterpret_cast<const unsigned char*>(server1_key_.data()));
- server_certs_.push_back(
- reinterpret_cast<const unsigned char*>(server0_cert_.data()));
- server_certs_.push_back(
- reinterpret_cast<const unsigned char*>(server1_cert_.data()));
- badserver_keys_sizes_.push_back(badserver_key_.size());
- badserver_certs_sizes_.push_back(badserver_cert_.size());
- server_keys_sizes_.push_back(server0_key_.size());
- server_keys_sizes_.push_back(server1_key_.size());
- server_certs_sizes_.push_back(server0_cert_.size());
- server_certs_sizes_.push_back(server1_cert_.size());
- }
-
- string badserver_key_;
- string badserver_cert_;
- string badclient_key_;
- string badclient_cert_;
- string server0_key_;
- string server0_cert_;
- string server1_key_;
- string server1_cert_;
- string client_key_;
- string client_cert_;
- string root_certs_;
- std::vector<const unsigned char*> badserver_keys_;
- std::vector<const unsigned char*> badserver_certs_;
- std::vector<const unsigned char*> server_keys_;
- std::vector<const unsigned char*> server_certs_;
- std::vector<unsigned int> badserver_keys_sizes_;
- std::vector<unsigned int> badserver_certs_sizes_;
- std::vector<unsigned int> server_keys_sizes_;
- std::vector<unsigned int> server_certs_sizes_;
- TsiSslHandshakerFactoryUniquePtr client_handshaker_factory_;
- TsiSslHandshakerFactoryUniquePtr server_handshaker_factory_;
- std::vector<const char*> client_alpn_protocols_;
- std::vector<const char*> server_alpn_protocols_;
- std::vector<unsigned char> client_alpn_protocols_lengths_;
- std::vector<unsigned char> server_alpn_protocols_lengths_;
- string matched_alpn_;
- SslTestConfig config_;
-};
-
-
-TEST_F(SslTransportSecurityTest, LoadInvalidRoots) {
- tsi_ssl_handshaker_factory* client_handshaker_factory;
- string invalid_roots("Invalid roots!");
- EXPECT_EQ(
- TSI_INVALID_ARGUMENT,
- tsi_create_ssl_client_handshaker_factory(
- NULL, 0, NULL, 0,
- reinterpret_cast<const unsigned char*>(invalid_roots.data()),
- invalid_roots.size(), NULL, NULL, 0, 0, &client_handshaker_factory));
-}
-
-TEST_F(SslTransportSecurityTest, Handshake) {
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, HandshakeClientAuthentication) {
- config_.do_client_authentication = true;
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, HandshakeSmallBuffer) {
- config_.handshake_buffer_size = 128;
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, HandshakeSNIExactDomain) {
- // server1 cert contains waterzooi.test.google.be in SAN.
- config_.subject_name_indication = "waterzooi.test.google.be";
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, HandshakeSNIWildstarDomain) {
- // server1 cert contains *.test.google.fr in SAN.
- config_.subject_name_indication = "juju.test.google.fr";
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, BadServerCertFailure) {
- config_.use_bad_server_cert = true;
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, BadClientCertFailure) {
- config_.use_bad_client_cert = true;
- config_.do_client_authentication = true;
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, AlpnClientNoServer) {
- config_.alpn_mode = ALPN_CLIENT_NO_SERVER;
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, AlpnServerNoClient) {
- config_.alpn_mode = ALPN_SERVER_NO_CLIENT;
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, AlpnClientServeMismatch) {
- config_.alpn_mode = ALPN_CLIENT_SERVER_MISMATCH;
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, AlpnClientServerOk) {
- config_.alpn_mode = ALPN_CLIENT_SERVER_OK;
- PerformHandshake();
-}
-
-TEST_F(SslTransportSecurityTest, PingPong) {
- PingPong();
-}
-
-TEST_F(SslTransportSecurityTest, RoundTrip) {
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(SslTransportSecurityTest, RoundTripSmallMessageBuffer) {
- config_.message_buffer_allocated_size = 42;
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(SslTransportSecurityTest, RoundTripSmallProtectedBufferSize) {
- config_.protected_buffer_size = 37;
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(SslTransportSecurityTest, RoundTripSmallReadBufferSize) {
- config_.read_buffer_allocated_size = 41;
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(SslTransportSecurityTest, RoundTripSmallClientFrames) {
- config_.set_client_max_output_protected_frame_size(39);
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-TEST_F(SslTransportSecurityTest, RoundTripSmallServerFrames) {
- config_.set_server_max_output_protected_frame_size(43);
- config_.client_message = small_message_;
- config_.server_message = big_message_;
- DoRoundTrip();
-}
-
-TEST_F(SslTransportSecurityTest, RoundTripOddBufferSizes) {
- int odd_sizes[] = {33, 67, 135, 271, 523};
- RandomPermutation<int> permute(odd_sizes, arraysize(odd_sizes),
- random_.get());
- permute.Permute();
- LOG(ERROR) << odd_sizes[0] << "\t" << odd_sizes[1] << "\t" << odd_sizes[2]
- << "\t" << odd_sizes[3] << "\t" << odd_sizes[4];
- config_.message_buffer_allocated_size = odd_sizes[0];
- config_.protected_buffer_size = odd_sizes[1];
- config_.read_buffer_allocated_size = odd_sizes[2];
- config_.set_client_max_output_protected_frame_size(odd_sizes[3]);
- config_.set_server_max_output_protected_frame_size(odd_sizes[4]);
- config_.client_message = big_message_;
- config_.server_message = small_message_;
- DoRoundTrip();
-}
-
-} // namespace
diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c
index 94252e36d0..5a42f03f5f 100644
--- a/src/core/tsi/transport_security.c
+++ b/src/core/tsi/transport_security.c
@@ -44,7 +44,7 @@ char* tsi_strdup(const char* src) {
if (!src) return NULL;
len = strlen(src) + 1;
dst = malloc(len);
- if (!dst) return NULL;
+ if (!dst) return NULL;
memcpy(dst, src, len);
return dst;
}
@@ -84,17 +84,15 @@ const char* tsi_result_to_string(tsi_result result) {
}
}
-
/* --- tsi_frame_protector common implementation. ---
Calls specific implementation after state/input validation. */
-tsi_result tsi_frame_protector_protect(
- tsi_frame_protector* self,
- const unsigned char* unprotected_bytes,
- uint32_t* unprotected_bytes_size,
- unsigned char* protected_output_frames,
- uint32_t* protected_output_frames_size) {
+tsi_result tsi_frame_protector_protect(tsi_frame_protector* self,
+ const unsigned char* unprotected_bytes,
+ uint32_t* unprotected_bytes_size,
+ unsigned char* protected_output_frames,
+ uint32_t* protected_output_frames_size) {
if (self == NULL || unprotected_bytes == NULL ||
unprotected_bytes_size == NULL || protected_output_frames == NULL ||
protected_output_frames_size == NULL) {
@@ -106,10 +104,8 @@ tsi_result tsi_frame_protector_protect(
}
tsi_result tsi_frame_protector_protect_flush(
- tsi_frame_protector* self,
- unsigned char* protected_output_frames,
- uint32_t* protected_output_frames_size,
- uint32_t* still_pending_size) {
+ tsi_frame_protector* self, unsigned char* protected_output_frames,
+ uint32_t* protected_output_frames_size, uint32_t* still_pending_size) {
if (self == NULL || protected_output_frames == NULL ||
protected_output_frames == NULL || still_pending_size == NULL) {
return TSI_INVALID_ARGUMENT;
@@ -120,10 +116,8 @@ tsi_result tsi_frame_protector_protect_flush(
}
tsi_result tsi_frame_protector_unprotect(
- tsi_frame_protector* self,
- const unsigned char* protected_frames_bytes,
- uint32_t* protected_frames_bytes_size,
- unsigned char* unprotected_bytes,
+ tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
+ uint32_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
uint32_t* unprotected_bytes_size) {
if (self == NULL || protected_frames_bytes == NULL ||
protected_frames_bytes_size == NULL || unprotected_bytes == NULL ||
@@ -140,7 +134,6 @@ void tsi_frame_protector_destroy(tsi_frame_protector* self) {
self->vtable->destroy(self);
}
-
/* --- tsi_handshaker common implementation. ---
Calls specific implementation after state/input validation. */
@@ -153,7 +146,6 @@ tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size);
}
-
tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker* self,
const unsigned char* bytes,
uint32_t* bytes_size) {
@@ -179,8 +171,7 @@ tsi_result tsi_handshaker_extract_peer(tsi_handshaker* self, tsi_peer* peer) {
}
tsi_result tsi_handshaker_create_frame_protector(
- tsi_handshaker* self,
- uint32_t* max_protected_frame_size,
+ tsi_handshaker* self, uint32_t* max_protected_frame_size,
tsi_frame_protector** protector) {
tsi_result result;
if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT;
@@ -201,7 +192,6 @@ void tsi_handshaker_destroy(tsi_handshaker* self) {
self->vtable->destroy(self);
}
-
/* --- tsi_peer implementation. --- */
const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* self,
@@ -227,7 +217,6 @@ tsi_peer_property tsi_init_peer_property(void) {
return property;
}
-
static void tsi_peer_destroy_list_property(tsi_peer_property* children,
uint32_t child_count) {
uint32_t i;
@@ -254,7 +243,7 @@ void tsi_peer_property_destruct(tsi_peer_property* property) {
/* Nothing to free. */
break;
}
- *property = tsi_init_peer_property(); /* Reset everything to 0. */
+ *property = tsi_init_peer_property(); /* Reset everything to 0. */
}
void tsi_peer_destruct(tsi_peer* self) {
diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h
index cf9a2b0195..9a20fa83a5 100644
--- a/src/core/tsi/transport_security.h
+++ b/src/core/tsi/transport_security.h
@@ -109,10 +109,10 @@ tsi_result tsi_construct_list_peer_property(const char* name,
tsi_peer_property* property);
/* Utils. */
-char* tsi_strdup(const char* src); /* Sadly, no strdup in C89. */
+char* tsi_strdup(const char* src); /* Sadly, no strdup in C89. */
#ifdef __cplusplus
}
#endif
-#endif /* __TRANSPORT_SECURITY_H_ */
+#endif /* __TRANSPORT_SECURITY_H_ */
diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
index 6be72c753a..76746a4b20 100644
--- a/src/core/tsi/transport_security_interface.h
+++ b/src/core/tsi/transport_security_interface.h
@@ -60,7 +60,6 @@ typedef enum {
const char* tsi_result_to_string(tsi_result result);
-
/* --- tsi_frame_protector object ---
This object protects and unprotects buffers once the handshake is done.
@@ -121,12 +120,11 @@ typedef struct tsi_frame_protector tsi_frame_protector;
if (result != TSI_OK) HandleError(result);
------------------------------------------------------------------------ */
-tsi_result tsi_frame_protector_protect(
- tsi_frame_protector* self,
- const unsigned char* unprotected_bytes,
- uint32_t* unprotected_bytes_size,
- unsigned char* protected_output_frames,
- uint32_t* protected_output_frames_size);
+tsi_result tsi_frame_protector_protect(tsi_frame_protector* self,
+ const unsigned char* unprotected_bytes,
+ uint32_t* unprotected_bytes_size,
+ unsigned char* protected_output_frames,
+ uint32_t* protected_output_frames_size);
/* Indicates that we need to flush the bytes buffered in the protector and get
the resulting frame.
@@ -137,10 +135,8 @@ tsi_result tsi_frame_protector_protect(
- still_pending_bytes is an output parameter indicating the number of bytes
that still need to be flushed from the protector.*/
tsi_result tsi_frame_protector_protect_flush(
- tsi_frame_protector* self,
- unsigned char* protected_output_frames,
- uint32_t* protected_output_frames_size,
- uint32_t* still_pending_size);
+ tsi_frame_protector* self, unsigned char* protected_output_frames,
+ uint32_t* protected_output_frames_size, uint32_t* still_pending_size);
/* Outputs unprotected bytes.
- protected_frames_bytes is an input only parameter and points to the
@@ -163,16 +159,13 @@ tsi_result tsi_frame_protector_protect_flush(
needs to be read before new protected data can be processed in which case
protected_frames_size will be set to 0. */
tsi_result tsi_frame_protector_unprotect(
- tsi_frame_protector* self,
- const unsigned char* protected_frames_bytes,
- uint32_t* protected_frames_bytes_size,
- unsigned char* unprotected_bytes,
+ tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
+ uint32_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
uint32_t* unprotected_bytes_size);
/* Destroys the tsi_frame_protector object. */
void tsi_frame_protector_destroy(tsi_frame_protector* self);
-
/* --- tsi_peer objects ---
tsi_peer objects are a set of properties. The peer owns the properties. */
@@ -180,23 +173,6 @@ void tsi_frame_protector_destroy(tsi_frame_protector* self);
/* This property is of type TSI_PEER_PROPERTY_STRING. */
#define TSI_CERTIFICATE_TYPE_PEER_PROPERTY "certificate_type"
-/* This property is of type TSI_PEER_PROPERTY_STRING. */
-#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name"
-
-/* This property is of type TSI_PEER_PROPERTY_LIST and the children contain
- unnamed (name == NULL) properties of type TSI_PEER_PROPERTY_STRING. */
-#define TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY \
- "x509_subject_alternative_names"
-
-/* This property is of type TSI_PEER_PROPERTY_STRING. */
-#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol"
-
-/* This property is of type TSI_PEER_PROPERTY_STRING. */
-#define TSI_MDB_USER_NAME_PEER_PROPERTY "mdb_user_name"
-
-/* This property is of type TSI_PEER_PROPERTY_SIGNED_INTEGER. */
-#define TSI_MDB_GAIA_ID_PEER_PROPERTY "mdb_gaia_id"
-
/* Properties of type TSI_PEER_PROPERTY_TYPE_STRING may contain NULL characters
just like C++ strings. The length field gives the length of the string. */
typedef enum {
@@ -350,7 +326,6 @@ tsi_result tsi_handshaker_get_result(tsi_handshaker* self);
#define tsi_handshaker_is_in_progress(h) \
(tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS)
-
/* This method may return TSI_FAILED_PRECONDITION if
tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise
assuming the handshaker is not in a fatal error state.
@@ -374,8 +349,7 @@ tsi_result tsi_handshaker_extract_peer(tsi_handshaker* self, tsi_peer* peer);
the handshaker is not in a fatal error state.
The caller is responsible for destroying the protector. */
tsi_result tsi_handshaker_create_frame_protector(
- tsi_handshaker* self,
- uint32_t* max_output_protected_frame_size,
+ tsi_handshaker* self, uint32_t* max_output_protected_frame_size,
tsi_frame_protector** protector);
/* This method releases the tsi_handshaker object. After this method is called,
@@ -386,4 +360,4 @@ void tsi_handshaker_destroy(tsi_handshaker* self);
}
#endif
-#endif /* __TRANSPORT_SECURITY_INTERFACE_H_ */
+#endif /* __TRANSPORT_SECURITY_INTERFACE_H_ */
diff --git a/src/core/tsi/transport_security_test_lib.cc b/src/core/tsi/transport_security_test_lib.cc
deleted file mode 100644
index 1b630c9578..0000000000
--- a/src/core/tsi/transport_security_test_lib.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- *
- * Copyright 2014, 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 "src/core/tsi/transport_security_test_lib.h"
-
-#include <memory>
-
-#include "base/commandlineflags.h"
-#include "src/core/tsi/transport_security_interface.h"
-#include "strings/escaping.h"
-#include "strings/strcat.h"
-#include <gtest/gtest.h>
-#include "util/random/mt_random.h"
-
-namespace {
-
-const char kPingRequest[] = "Ping";
-const char kPongResponse[] = "Pong";
-const int kBigMessageSize = 17000;
-
-} // namespace
-
-namespace tsi {
-namespace test {
-
-TransportSecurityTest::TransportSecurityTest() : random_(new MTRandom()) {
- small_message_ = "Chapi Chapo";
- big_message_ = RandomString(kBigMessageSize);
-}
-
-string TransportSecurityTest::RandomString(int size) {
- std::unique_ptr<char[]> buffer(new char[size]);
- for (int i = 0; i < size; i++) {
- buffer[i] = random_->Rand8();
- }
- return string(buffer.get(), size);
-}
-
-void TransportSecurityTest::SendBytesToPeer(bool is_client, unsigned char* buf,
- unsigned int buf_size) {
- string& channel = is_client ? to_server_channel_ : to_client_channel_;
- LOG(INFO) << (is_client ? "Client:" : "Server") << " sending " << buf_size
- << " bytes to peer.";
- channel.append(reinterpret_cast<const char*>(buf), buf_size);
-}
-
-void TransportSecurityTest::ReadBytesFromPeer(bool is_client,
- unsigned char* buf,
- unsigned int* buf_size) {
- string& channel = is_client ? to_client_channel_ : to_server_channel_;
- unsigned int to_read =
- *buf_size < channel.size() ? *buf_size : channel.size();
- memcpy(buf, channel.data(), to_read);
- *buf_size = to_read;
- channel.erase(0, to_read);
- LOG(INFO) << (is_client ? "Client:" : "Server") << " read " << to_read
- << " bytes from peer.";
-}
-
-void TransportSecurityTest::DoHandshakeStep(bool is_client,
- unsigned int buf_allocated_size,
- tsi_handshaker* handshaker,
- string* remaining_bytes) {
- tsi_result result = TSI_OK;
- std::unique_ptr<unsigned char[]> buf(new unsigned char[buf_allocated_size]);
- unsigned int buf_offset;
- unsigned int buf_size;
- // See if we need to send some bytes to the peer.
- do {
- unsigned int buf_size_to_send = buf_allocated_size;
- result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf.get(),
- &buf_size_to_send);
- if (buf_size_to_send > 0) {
- SendBytesToPeer(is_client, buf.get(), buf_size_to_send);
- }
- } while (result == TSI_INCOMPLETE_DATA);
- if (!tsi_handshaker_is_in_progress(handshaker)) return;
-
- do {
- // Read bytes from the peer.
- buf_size = buf_allocated_size;
- buf_offset = 0;
- ReadBytesFromPeer(is_client, buf.get(), &buf_size);
- if (buf_size == 0) break;
-
- // Process the bytes from the peer. We have to be careful as these bytes
- // may contain non-handshake data (protected data). If this is the case,
- // we will exit from the loop with buf_size > 0.
- unsigned int consumed_by_handshaker = buf_size;
- result = tsi_handshaker_process_bytes_from_peer(handshaker, buf.get(),
- &consumed_by_handshaker);
- buf_size -= consumed_by_handshaker;
- buf_offset += consumed_by_handshaker;
- } while (result == TSI_INCOMPLETE_DATA);
-
- if (!tsi_handshaker_is_in_progress(handshaker)) {
- remaining_bytes->assign(
- reinterpret_cast<const char*>(buf.get()) + buf_offset, buf_size);
- }
-}
-
-void TransportSecurityTest::PerformHandshake() {
- SetupHandshakers();
- string remaining_bytes;
- do {
- DoHandshakeStep(true, config()->handshake_buffer_size,
- client_handshaker_.get(), &remaining_bytes);
- EXPECT_EQ(0, remaining_bytes.size());
- DoHandshakeStep(false, config()->handshake_buffer_size,
- server_handshaker_.get(), &remaining_bytes);
- EXPECT_EQ(0, remaining_bytes.size());
- } while (tsi_handshaker_is_in_progress(client_handshaker_.get()) ||
- tsi_handshaker_is_in_progress(server_handshaker_.get()));
- CheckHandshakeResults();
-}
-
-void TransportSecurityTest::SendMessageToPeer(
- bool is_client, tsi_frame_protector* protector, const string& message,
- unsigned int protected_buffer_size) {
- std::unique_ptr<unsigned char[]> protected_buffer(
- new unsigned char[protected_buffer_size]);
- unsigned int message_size = message.size();
- const unsigned char* message_bytes =
- reinterpret_cast<const unsigned char*>(message.data());
- tsi_result result = TSI_OK;
- while (message_size > 0 && result == TSI_OK) {
- unsigned int protected_buffer_size_to_send = protected_buffer_size;
- unsigned int processed_message_size = message_size;
- result = tsi_frame_protector_protect(
- protector, message_bytes, &processed_message_size,
- protected_buffer.get(), &protected_buffer_size_to_send);
- EXPECT_EQ(TSI_OK, result);
- SendBytesToPeer(is_client, protected_buffer.get(),
- protected_buffer_size_to_send);
- message_bytes += processed_message_size;
- message_size -= processed_message_size;
-
- // Flush if we're done.
- if (message_size == 0) {
- unsigned int still_pending_size;
- do {
- protected_buffer_size_to_send = protected_buffer_size;
- result = tsi_frame_protector_protect_flush(
- protector, protected_buffer.get(), &protected_buffer_size_to_send,
- &still_pending_size);
- EXPECT_EQ(TSI_OK, result);
- SendBytesToPeer(is_client, protected_buffer.get(),
- protected_buffer_size_to_send);
- } while (still_pending_size > 0 && result == TSI_OK);
- EXPECT_EQ(TSI_OK, result);
- }
- }
- EXPECT_EQ(TSI_OK, result);
-}
-
-void TransportSecurityTest::ReceiveMessageFromPeer(
- bool is_client, tsi_frame_protector* protector,
- unsigned int read_buf_allocated_size,
- unsigned int message_buf_allocated_size, string* message) {
- std::unique_ptr<unsigned char[]> read_buffer(
- new unsigned char[read_buf_allocated_size]);
- unsigned int read_offset = 0;
- unsigned int read_from_peer_size = 0;
- std::unique_ptr<unsigned char[]> message_buffer(
- new unsigned char[message_buf_allocated_size]);
- tsi_result result = TSI_OK;
- bool done = false;
- while (!done && result == TSI_OK) {
- if (read_from_peer_size == 0) {
- read_from_peer_size = read_buf_allocated_size;
- ReadBytesFromPeer(is_client, read_buffer.get(), &read_from_peer_size);
- read_offset = 0;
- }
- if (read_from_peer_size == 0) done = true;
- unsigned int message_buffer_size;
- do {
- message_buffer_size = message_buf_allocated_size;
- unsigned int processed_size = read_from_peer_size;
- result = tsi_frame_protector_unprotect(
- protector, read_buffer.get() + read_offset, &processed_size,
- message_buffer.get(), &message_buffer_size);
- EXPECT_EQ(TSI_OK, result);
- if (message_buffer_size > 0) {
- LOG(INFO) << "Wrote " << message_buffer_size << " bytes to message.";
- message->append(reinterpret_cast<const char*>(message_buffer.get()),
- message_buffer_size);
- }
- read_offset += processed_size;
- read_from_peer_size -= processed_size;
- } while ((read_from_peer_size > 0 || message_buffer_size > 0) &&
- result == TSI_OK);
- EXPECT_EQ(TSI_OK, result);
- }
- EXPECT_EQ(TSI_OK, result);
-}
-
-void TransportSecurityTest::DoRoundTrip(const string& request,
- const string& response) {
- PerformHandshake();
-
- tsi_frame_protector* client_frame_protector;
- tsi_frame_protector* server_frame_protector;
- unsigned int client_max_output_protected_frame_size =
- config()->client_max_output_protected_frame_size();
- EXPECT_EQ(TSI_OK,
- tsi_handshaker_create_frame_protector(
- client_handshaker_.get(),
- config()->use_client_default_max_output_protected_frame_size()
- ? nullptr
- : &client_max_output_protected_frame_size,
- &client_frame_protector));
-
- unsigned int server_max_output_protected_frame_size =
- config()->server_max_output_protected_frame_size();
- EXPECT_EQ(TSI_OK,
- tsi_handshaker_create_frame_protector(
- server_handshaker_.get(),
- config()->use_server_default_max_output_protected_frame_size()
- ? nullptr
- : &server_max_output_protected_frame_size,
- &server_frame_protector));
-
- SendMessageToPeer(true, client_frame_protector, request,
- config()->protected_buffer_size);
- string retrieved_request;
- ReceiveMessageFromPeer(
- false, server_frame_protector, config()->read_buffer_allocated_size,
- config()->message_buffer_allocated_size, &retrieved_request);
- EXPECT_EQ(request.size(), retrieved_request.size());
- EXPECT_EQ(strings::b2a_hex(request), strings::b2a_hex(retrieved_request));
-
- SendMessageToPeer(false, server_frame_protector, response,
- config()->protected_buffer_size);
- string retrieved_response;
- ReceiveMessageFromPeer(
- true, client_frame_protector, config()->read_buffer_allocated_size,
- config()->message_buffer_allocated_size, &retrieved_response);
- EXPECT_EQ(response.size(), retrieved_response.size());
- EXPECT_EQ(strings::b2a_hex(response), strings::b2a_hex(retrieved_response));
-
- tsi_frame_protector_destroy(client_frame_protector);
- tsi_frame_protector_destroy(server_frame_protector);
-}
-
-void TransportSecurityTest::DoRoundTrip() {
- DoRoundTrip(config()->client_message, config()->server_message);
-}
-void TransportSecurityTest::PingPong() {
- PerformHandshake();
-
- unsigned char to_server[4096];
- unsigned char to_client[4096];
- unsigned int max_frame_size = sizeof(to_client);
- tsi_frame_protector* client_frame_protector;
- tsi_frame_protector* server_frame_protector;
- EXPECT_EQ(
- tsi_handshaker_create_frame_protector(
- client_handshaker_.get(), &max_frame_size, &client_frame_protector),
- TSI_OK);
- EXPECT_EQ(max_frame_size, sizeof(to_client));
- EXPECT_EQ(
- tsi_handshaker_create_frame_protector(
- server_handshaker_.get(), &max_frame_size, &server_frame_protector),
- TSI_OK);
- EXPECT_EQ(max_frame_size, sizeof(to_client));
-
- // Send Ping.
- unsigned int ping_length = strlen(kPingRequest);
- unsigned int protected_size = sizeof(to_server);
- EXPECT_EQ(tsi_frame_protector_protect(
- client_frame_protector,
- reinterpret_cast<const unsigned char*>(kPingRequest),
- &ping_length, to_server, &protected_size),
- TSI_OK);
- EXPECT_EQ(ping_length, strlen(kPingRequest));
- EXPECT_EQ(protected_size, 0);
- protected_size = sizeof(to_server);
- unsigned int still_pending_size;
- EXPECT_EQ(
- tsi_frame_protector_protect_flush(client_frame_protector, to_server,
- &protected_size, &still_pending_size),
- TSI_OK);
- EXPECT_EQ(still_pending_size, 0);
- EXPECT_GT(protected_size, strlen(kPingRequest));
-
- // Receive Ping.
- unsigned int unprotected_size = sizeof(to_server);
- unsigned int saved_protected_size = protected_size;
- EXPECT_EQ(tsi_frame_protector_unprotect(server_frame_protector, to_server,
- &protected_size, to_server,
- &unprotected_size),
- TSI_OK);
- EXPECT_EQ(saved_protected_size, protected_size);
- EXPECT_EQ(ping_length, unprotected_size);
- EXPECT_EQ(string(kPingRequest),
- string(reinterpret_cast<const char*>(to_server), unprotected_size));
-
- // Send back Pong.
- unsigned int pong_length = strlen(kPongResponse);
- protected_size = sizeof(to_client);
- EXPECT_EQ(tsi_frame_protector_protect(
- server_frame_protector,
- reinterpret_cast<const unsigned char*>(kPongResponse),
- &pong_length, to_client, &protected_size),
- TSI_OK);
- EXPECT_EQ(pong_length, strlen(kPongResponse));
- EXPECT_EQ(protected_size, 0);
- protected_size = sizeof(to_client);
- EXPECT_EQ(
- tsi_frame_protector_protect_flush(server_frame_protector, to_client,
- &protected_size, &still_pending_size),
- TSI_OK);
- EXPECT_EQ(still_pending_size, 0);
- EXPECT_GT(protected_size, strlen(kPongResponse));
-
- // Receive Pong.
- unprotected_size = sizeof(to_server);
- saved_protected_size = protected_size;
- EXPECT_EQ(tsi_frame_protector_unprotect(client_frame_protector, to_client,
- &protected_size, to_client,
- &unprotected_size),
- TSI_OK);
- EXPECT_EQ(saved_protected_size, protected_size);
- EXPECT_EQ(pong_length, unprotected_size);
- EXPECT_EQ(string(kPongResponse),
- string(reinterpret_cast<const char*>(to_client), unprotected_size));
-
- tsi_frame_protector_destroy(client_frame_protector);
- tsi_frame_protector_destroy(server_frame_protector);
-}
-
-} // namespace test
-} // namespace tsi
diff --git a/src/core/tsi/transport_security_test_lib.h b/src/core/tsi/transport_security_test_lib.h
deleted file mode 100644
index 8c9c764c91..0000000000
--- a/src/core/tsi/transport_security_test_lib.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *
- * Copyright 2014, 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 __TRANSPORT_SECURITY_TEST_LIB_H_
-#define __TRANSPORT_SECURITY_TEST_LIB_H_
-
-#include <memory>
-
-#include "base/commandlineflags.h"
-#include "src/core/tsi/transport_security_interface.h"
-#include "strings/strcat.h"
-#include <gtest/gtest.h>
-#include "util/random/mt_random.h"
-
-namespace tsi {
-namespace test {
-
-class TestConfig {
- public:
- TestConfig()
- : client_message("Chapi Chapo"),
- server_message("Chapi Chapo"),
- handshake_buffer_size(4096),
- read_buffer_allocated_size(4096),
- message_buffer_allocated_size(4096),
- protected_buffer_size(16384),
- use_client_default_max_output_protected_frame_size_(true),
- use_server_default_max_output_protected_frame_size_(true),
- client_max_output_protected_frame_size_(0),
- server_max_output_protected_frame_size_(0) {}
-
- void set_client_max_output_protected_frame_size(unsigned int size) {
- use_client_default_max_output_protected_frame_size_ = false;
- client_max_output_protected_frame_size_ = size;
- }
- void set_server_max_output_protected_frame_size(unsigned int size) {
- use_server_default_max_output_protected_frame_size_ = false;
- server_max_output_protected_frame_size_ = size;
- }
- bool use_client_default_max_output_protected_frame_size() const {
- return use_client_default_max_output_protected_frame_size_;
- }
- bool use_server_default_max_output_protected_frame_size() const {
- return use_server_default_max_output_protected_frame_size_;
- }
- unsigned int client_max_output_protected_frame_size() const {
- return client_max_output_protected_frame_size_;
- }
- unsigned int server_max_output_protected_frame_size() const {
- return server_max_output_protected_frame_size_;
- }
-
- string client_message;
- string server_message;
- unsigned int handshake_buffer_size;
- unsigned int read_buffer_allocated_size;
- unsigned int message_buffer_allocated_size;
- unsigned int protected_buffer_size;
-
- private:
- bool use_client_default_max_output_protected_frame_size_;
- bool use_server_default_max_output_protected_frame_size_;
- unsigned int client_max_output_protected_frame_size_;
- unsigned int server_max_output_protected_frame_size_;
-};
-
-
-struct TsiHandshakerDeleter {
- inline void operator()(tsi_handshaker* ptr) { tsi_handshaker_destroy(ptr); }
-};
-typedef std::unique_ptr<tsi_handshaker, TsiHandshakerDeleter>
- TsiHandshakerUniquePtr;
-
-class TransportSecurityTest : public ::testing::Test {
- protected:
- TransportSecurityTest();
- virtual ~TransportSecurityTest() {}
- virtual const TestConfig* config() = 0;
- string RandomString(int size);
- virtual void SetupHandshakers() = 0;
- // An implementation-specific verification of the validity of the handshake.
- virtual void CheckHandshakeResults() = 0;
- // Do a full handshake.
- void PerformHandshake();
- // Send a protected message between the client and server.
- void SendMessageToPeer(bool is_client, tsi_frame_protector* protector,
- const string& message,
- unsigned int protected_buffer_size);
- void ReceiveMessageFromPeer(bool is_client, tsi_frame_protector* protector,
- unsigned int read_buf_allocated_size,
- unsigned int message_buf_allocated_size,
- string* message);
-
- // A simple test that does a handshake and sends a message back and forth
- void PingPong();
- // A complicated test that can be configured by modifying config().
- void DoRoundTrip();
-
- TsiHandshakerUniquePtr client_handshaker_;
- TsiHandshakerUniquePtr server_handshaker_;
-
- string small_message_;
- string big_message_;
- std::unique_ptr<RandomBase> random_;
-
- private:
- // Functions to send raw bytes between the client and server.
- void SendBytesToPeer(bool is_client, unsigned char* buf,
- unsigned int buf_size);
- void ReadBytesFromPeer(bool is_client, unsigned char* buf,
- unsigned int* buf_size);
- // Do a single step of the handshake.
- void DoHandshakeStep(bool is_client, unsigned int buf_allocated_size,
- tsi_handshaker* handshaker, string* remaining_bytes);
- void DoRoundTrip(const string& request, const string& response);
-
- string to_server_channel_;
- string to_client_channel_;
-};
-
-} // namespace test
-} // namespace tsi
-
-#endif // __TRANSPORT_SECURITY_TEST_LIB_H_