aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/ext/transport/chttp2/server/chttp2_server.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ext/transport/chttp2/server/chttp2_server.cc')
-rw-r--r--src/core/ext/transport/chttp2/server/chttp2_server.cc66
1 files changed, 58 insertions, 8 deletions
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc
index 3f8a26ae32..33d2b22aa5 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.cc
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc
@@ -37,8 +37,10 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/channel/handshaker_registry.h"
+#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
@@ -53,6 +55,8 @@ typedef struct {
grpc_closure tcp_server_shutdown_complete;
grpc_closure* server_destroy_listener_done;
grpc_handshake_manager* pending_handshake_mgrs;
+ grpc_core::RefCountedPtr<grpc_core::channelz::ListenSocketNode>
+ channelz_listen_socket;
} server_state;
typedef struct {
@@ -67,6 +71,7 @@ typedef struct {
grpc_timer timer;
grpc_closure on_timeout;
grpc_closure on_receive_settings;
+ grpc_pollset_set* interested_parties;
} server_connection_state;
static void server_connection_state_unref(
@@ -76,6 +81,9 @@ static void server_connection_state_unref(
GRPC_CHTTP2_UNREF_TRANSPORT(connection_state->transport,
"receive settings timeout");
}
+ grpc_pollset_set_del_pollset(connection_state->interested_parties,
+ connection_state->accepting_pollset);
+ grpc_pollset_set_destroy(connection_state->interested_parties);
gpr_free(connection_state);
}
}
@@ -108,9 +116,16 @@ static void on_handshake_done(void* arg, grpc_error* error) {
server_connection_state* connection_state =
static_cast<server_connection_state*>(args->user_data);
gpr_mu_lock(&connection_state->svr_state->mu);
+ grpc_resource_user* resource_user = grpc_server_get_default_resource_user(
+ connection_state->svr_state->server);
if (error != GRPC_ERROR_NONE || connection_state->svr_state->shutdown) {
const char* error_str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "Handshaking failed: %s", error_str);
+ grpc_resource_user* resource_user = grpc_server_get_default_resource_user(
+ connection_state->svr_state->server);
+ if (resource_user != nullptr) {
+ grpc_resource_user_free(resource_user, GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
+ }
if (error == GRPC_ERROR_NONE && args->endpoint != nullptr) {
// We were shut down after handshaking completed successfully, so
// destroy the endpoint here.
@@ -129,11 +144,12 @@ static void on_handshake_done(void* arg, grpc_error* error) {
// handshaker may have handed off the connection to some external
// code, so we can just clean up here without creating a transport.
if (args->endpoint != nullptr) {
- grpc_transport* transport =
- grpc_create_chttp2_transport(args->args, args->endpoint, false);
+ grpc_transport* transport = grpc_create_chttp2_transport(
+ args->args, args->endpoint, false, resource_user);
grpc_server_setup_transport(
connection_state->svr_state->server, transport,
- connection_state->accepting_pollset, args->args);
+ connection_state->accepting_pollset, args->args,
+ grpc_chttp2_transport_get_socket_uuid(transport), resource_user);
// Use notify_on_receive_settings callback to enforce the
// handshake deadline.
connection_state->transport =
@@ -152,6 +168,11 @@ static void on_handshake_done(void* arg, grpc_error* error) {
connection_state, grpc_schedule_on_exec_ctx);
grpc_timer_init(&connection_state->timer, connection_state->deadline,
&connection_state->on_timeout);
+ } else {
+ if (resource_user != nullptr) {
+ grpc_resource_user_free(resource_user,
+ GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
+ }
}
}
grpc_handshake_manager_pending_list_remove(
@@ -176,6 +197,20 @@ static void on_accept(void* arg, grpc_endpoint* tcp,
gpr_free(acceptor);
return;
}
+ grpc_resource_user* resource_user =
+ grpc_server_get_default_resource_user(state->server);
+ if (resource_user != nullptr &&
+ !grpc_resource_user_safe_alloc(resource_user,
+ GRPC_RESOURCE_QUOTA_CHANNEL_SIZE)) {
+ gpr_log(
+ GPR_ERROR,
+ "Memory quota exhausted, rejecting the connection, no handshaking.");
+ gpr_mu_unlock(&state->mu);
+ grpc_endpoint_shutdown(tcp, GRPC_ERROR_NONE);
+ grpc_endpoint_destroy(tcp);
+ gpr_free(acceptor);
+ return;
+ }
grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create();
grpc_handshake_manager_pending_list_add(&state->pending_handshake_mgrs,
handshake_mgr);
@@ -189,7 +224,11 @@ static void on_accept(void* arg, grpc_endpoint* tcp,
connection_state->accepting_pollset = accepting_pollset;
connection_state->acceptor = acceptor;
connection_state->handshake_mgr = handshake_mgr;
+ connection_state->interested_parties = grpc_pollset_set_create();
+ grpc_pollset_set_add_pollset(connection_state->interested_parties,
+ connection_state->accepting_pollset);
grpc_handshakers_add(HANDSHAKER_SERVER, state->args,
+ connection_state->interested_parties,
connection_state->handshake_mgr);
const grpc_arg* timeout_arg =
grpc_channel_args_find(state->args, GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS);
@@ -197,10 +236,10 @@ static void on_accept(void* arg, grpc_endpoint* tcp,
grpc_core::ExecCtx::Get()->Now() +
grpc_channel_arg_get_integer(timeout_arg,
{120 * GPR_MS_PER_SEC, 1, INT_MAX});
- grpc_handshake_manager_do_handshake(
- connection_state->handshake_mgr, nullptr /* interested_parties */, tcp,
- state->args, connection_state->deadline, acceptor, on_handshake_done,
- connection_state);
+ grpc_handshake_manager_do_handshake(connection_state->handshake_mgr, tcp,
+ state->args, connection_state->deadline,
+ acceptor, on_handshake_done,
+ connection_state);
}
/* Server callback: start listening on our ports */
@@ -223,6 +262,7 @@ static void tcp_server_shutdown_complete(void* arg, grpc_error* error) {
GPR_ASSERT(state->shutdown);
grpc_handshake_manager_pending_list_shutdown_all(
state->pending_handshake_mgrs, GRPC_ERROR_REF(error));
+ state->channelz_listen_socket.reset();
gpr_mu_unlock(&state->mu);
// Flush queued work before destroying handshaker factory, since that
// may do a synchronous unref.
@@ -262,6 +302,8 @@ grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr,
server_state* state = nullptr;
grpc_error** errors = nullptr;
size_t naddrs = 0;
+ const grpc_arg* arg = nullptr;
+ intptr_t socket_uuid = 0;
*port_num = -1;
@@ -323,9 +365,17 @@ grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr,
}
grpc_resolved_addresses_destroy(resolved);
+ arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ);
+ if (grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT)) {
+ state->channelz_listen_socket =
+ grpc_core::MakeRefCounted<grpc_core::channelz::ListenSocketNode>(
+ grpc_core::UniquePtr<char>(gpr_strdup(addr)));
+ socket_uuid = state->channelz_listen_socket->uuid();
+ }
+
/* Register with the server only upon success */
grpc_server_add_listener(server, state, server_start_listener,
- server_destroy_listener);
+ server_destroy_listener, socket_uuid);
goto done;
/* Error path: cleanup and return */