|
|
|
@ -35,6 +35,7 @@ |
|
|
|
|
|
|
|
|
|
#include "src/core/channel/http_filter.h" |
|
|
|
|
#include "src/core/channel/http_server_filter.h" |
|
|
|
|
#include "src/core/iomgr/endpoint.h" |
|
|
|
|
#include "src/core/iomgr/resolve_address.h" |
|
|
|
|
#include "src/core/iomgr/tcp_server.h" |
|
|
|
|
#include "src/core/security/security_context.h" |
|
|
|
@ -43,8 +44,27 @@ |
|
|
|
|
#include "src/core/transport/chttp2_transport.h" |
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
#include <grpc/support/log.h> |
|
|
|
|
#include <grpc/support/sync.h> |
|
|
|
|
#include <grpc/support/useful.h> |
|
|
|
|
|
|
|
|
|
typedef struct grpc_server_secure_state { |
|
|
|
|
grpc_server *server; |
|
|
|
|
grpc_tcp_server *tcp; |
|
|
|
|
int is_shutdown; |
|
|
|
|
gpr_mu mu; |
|
|
|
|
gpr_refcount refcount; |
|
|
|
|
} grpc_server_secure_state; |
|
|
|
|
|
|
|
|
|
static void state_ref(grpc_server_secure_state *state) { |
|
|
|
|
gpr_ref(&state->refcount); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void state_unref(grpc_server_secure_state *state) { |
|
|
|
|
if (gpr_unref(&state->refcount)) { |
|
|
|
|
gpr_free(state); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static grpc_transport_setup_result setup_transport(void *server, |
|
|
|
|
grpc_transport *transport, |
|
|
|
|
grpc_mdctx *mdctx) { |
|
|
|
@ -54,44 +74,62 @@ static grpc_transport_setup_result setup_transport(void *server, |
|
|
|
|
GPR_ARRAY_SIZE(extra_filters), mdctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void on_secure_transport_setup_done(void *server, |
|
|
|
|
static void on_secure_transport_setup_done(void *statep, |
|
|
|
|
grpc_security_status status, |
|
|
|
|
grpc_endpoint *secure_endpoint) { |
|
|
|
|
grpc_server_secure_state *state = statep; |
|
|
|
|
if (status == GRPC_SECURITY_OK) { |
|
|
|
|
grpc_create_chttp2_transport( |
|
|
|
|
setup_transport, server, grpc_server_get_channel_args(server), |
|
|
|
|
secure_endpoint, NULL, 0, grpc_mdctx_create(), 0); |
|
|
|
|
gpr_mu_lock(&state->mu); |
|
|
|
|
if (!state->is_shutdown) { |
|
|
|
|
grpc_create_chttp2_transport( |
|
|
|
|
setup_transport, state->server, |
|
|
|
|
grpc_server_get_channel_args(state->server), |
|
|
|
|
secure_endpoint, NULL, 0, grpc_mdctx_create(), 0); |
|
|
|
|
} else { |
|
|
|
|
/* We need to consume this here, because the server may already have gone
|
|
|
|
|
* away. */ |
|
|
|
|
grpc_endpoint_destroy(secure_endpoint); |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&state->mu); |
|
|
|
|
} else { |
|
|
|
|
gpr_log(GPR_ERROR, "Secure transport failed with error %d", status); |
|
|
|
|
} |
|
|
|
|
state_unref(state); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void on_accept(void *server, grpc_endpoint *tcp) { |
|
|
|
|
const grpc_channel_args *args = grpc_server_get_channel_args(server); |
|
|
|
|
static void on_accept(void *statep, grpc_endpoint *tcp) { |
|
|
|
|
grpc_server_secure_state *state = statep; |
|
|
|
|
const grpc_channel_args *args = grpc_server_get_channel_args(state->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); |
|
|
|
|
state_ref(state); |
|
|
|
|
grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, state); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Note: the following code is the same with server_chttp2.c */ |
|
|
|
|
|
|
|
|
|
/* Server callback: start listening on our ports */ |
|
|
|
|
static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, |
|
|
|
|
static void start(grpc_server *server, void *statep, grpc_pollset **pollsets, |
|
|
|
|
size_t pollset_count) { |
|
|
|
|
grpc_tcp_server *tcp = tcpp; |
|
|
|
|
grpc_tcp_server_start(tcp, pollsets, pollset_count, on_accept, server); |
|
|
|
|
grpc_server_secure_state *state = statep; |
|
|
|
|
grpc_tcp_server_start(state->tcp, pollsets, pollset_count, on_accept, state); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Server callback: destroy the tcp listener (so we don't generate further
|
|
|
|
|
callbacks) */ |
|
|
|
|
static void destroy(grpc_server *server, void *tcpp) { |
|
|
|
|
grpc_tcp_server *tcp = tcpp; |
|
|
|
|
grpc_tcp_server_destroy(tcp); |
|
|
|
|
static void destroy(grpc_server *server, void *statep) { |
|
|
|
|
grpc_server_secure_state *state = statep; |
|
|
|
|
gpr_mu_lock(&state->mu); |
|
|
|
|
state->is_shutdown = 1; |
|
|
|
|
grpc_tcp_server_destroy(state->tcp); |
|
|
|
|
gpr_mu_unlock(&state->mu); |
|
|
|
|
state_unref(state); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { |
|
|
|
|
grpc_resolved_addresses *resolved = NULL; |
|
|
|
|
grpc_tcp_server *tcp = NULL; |
|
|
|
|
grpc_server_secure_state *state = NULL; |
|
|
|
|
size_t i; |
|
|
|
|
unsigned count = 0; |
|
|
|
|
int port_num = -1; |
|
|
|
@ -132,8 +170,15 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { |
|
|
|
|
} |
|
|
|
|
grpc_resolved_addresses_destroy(resolved); |
|
|
|
|
|
|
|
|
|
state = gpr_malloc(sizeof(*state)); |
|
|
|
|
state->server = server; |
|
|
|
|
state->tcp = tcp; |
|
|
|
|
state->is_shutdown = 0; |
|
|
|
|
gpr_mu_init(&state->mu); |
|
|
|
|
gpr_ref_init(&state->refcount, 1); |
|
|
|
|
|
|
|
|
|
/* Register with the server only upon success */ |
|
|
|
|
grpc_server_add_listener(server, tcp, start, destroy); |
|
|
|
|
grpc_server_add_listener(server, state, start, destroy); |
|
|
|
|
|
|
|
|
|
return port_num; |
|
|
|
|
|
|
|
|
|