|
|
|
@ -28,6 +28,7 @@ |
|
|
|
|
#include <utility> |
|
|
|
|
|
|
|
|
|
#include "absl/base/attributes.h" |
|
|
|
|
#include "absl/functional/any_invocable.h" |
|
|
|
|
#include "absl/log/check.h" |
|
|
|
|
#include "absl/status/status.h" |
|
|
|
|
#include "absl/strings/str_cat.h" |
|
|
|
@ -79,11 +80,11 @@ class SecurityHandshaker : public Handshaker { |
|
|
|
|
grpc_security_connector* connector, |
|
|
|
|
const ChannelArgs& args); |
|
|
|
|
~SecurityHandshaker() override; |
|
|
|
|
void Shutdown(grpc_error_handle why) override; |
|
|
|
|
void DoHandshake(grpc_tcp_server_acceptor* acceptor, |
|
|
|
|
grpc_closure* on_handshake_done, |
|
|
|
|
HandshakerArgs* args) override; |
|
|
|
|
const char* name() const override { return "security"; } |
|
|
|
|
absl::string_view name() const override { return "security"; } |
|
|
|
|
void DoHandshake( |
|
|
|
|
HandshakerArgs* args, |
|
|
|
|
absl::AnyInvocable<void(absl::Status)> on_handshake_done) override; |
|
|
|
|
void Shutdown(absl::Status error) override; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
grpc_error_handle DoHandshakerNextLocked(const unsigned char* bytes_received, |
|
|
|
@ -92,12 +93,11 @@ class SecurityHandshaker : public Handshaker { |
|
|
|
|
grpc_error_handle OnHandshakeNextDoneLocked( |
|
|
|
|
tsi_result result, const unsigned char* bytes_to_send, |
|
|
|
|
size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result); |
|
|
|
|
void HandshakeFailedLocked(grpc_error_handle error); |
|
|
|
|
void CleanupArgsForFailureLocked(); |
|
|
|
|
void HandshakeFailedLocked(absl::Status error); |
|
|
|
|
void Finish(absl::Status status); |
|
|
|
|
|
|
|
|
|
static void OnHandshakeDataReceivedFromPeerFn(void* arg, |
|
|
|
|
grpc_error_handle error); |
|
|
|
|
static void OnHandshakeDataSentToPeerFn(void* arg, grpc_error_handle error); |
|
|
|
|
void OnHandshakeDataReceivedFromPeerFn(absl::Status error); |
|
|
|
|
void OnHandshakeDataSentToPeerFn(absl::Status error); |
|
|
|
|
static void OnHandshakeDataReceivedFromPeerFnScheduler( |
|
|
|
|
void* arg, grpc_error_handle error); |
|
|
|
|
static void OnHandshakeDataSentToPeerFnScheduler(void* arg, |
|
|
|
@ -117,16 +117,14 @@ class SecurityHandshaker : public Handshaker { |
|
|
|
|
Mutex mu_; |
|
|
|
|
|
|
|
|
|
bool is_shutdown_ = false; |
|
|
|
|
// Read buffer to destroy after a shutdown.
|
|
|
|
|
grpc_slice_buffer* read_buffer_to_destroy_ = nullptr; |
|
|
|
|
|
|
|
|
|
// State saved while performing the handshake.
|
|
|
|
|
HandshakerArgs* args_ = nullptr; |
|
|
|
|
grpc_closure* on_handshake_done_ = nullptr; |
|
|
|
|
absl::AnyInvocable<void(absl::Status)> on_handshake_done_; |
|
|
|
|
|
|
|
|
|
size_t handshake_buffer_size_; |
|
|
|
|
unsigned char* handshake_buffer_; |
|
|
|
|
grpc_slice_buffer outgoing_; |
|
|
|
|
SliceBuffer outgoing_; |
|
|
|
|
grpc_closure on_handshake_data_sent_to_peer_; |
|
|
|
|
grpc_closure on_handshake_data_received_from_peer_; |
|
|
|
|
grpc_closure on_peer_checked_; |
|
|
|
@ -146,7 +144,6 @@ SecurityHandshaker::SecurityHandshaker(tsi_handshaker* handshaker, |
|
|
|
|
static_cast<uint8_t*>(gpr_malloc(handshake_buffer_size_))), |
|
|
|
|
max_frame_size_( |
|
|
|
|
std::max(0, args.GetInt(GRPC_ARG_TSI_MAX_FRAME_SIZE).value_or(0))) { |
|
|
|
|
grpc_slice_buffer_init(&outgoing_); |
|
|
|
|
GRPC_CLOSURE_INIT(&on_peer_checked_, &SecurityHandshaker::OnPeerCheckedFn, |
|
|
|
|
this, grpc_schedule_on_exec_ctx); |
|
|
|
|
} |
|
|
|
@ -154,45 +151,30 @@ SecurityHandshaker::SecurityHandshaker(tsi_handshaker* handshaker, |
|
|
|
|
SecurityHandshaker::~SecurityHandshaker() { |
|
|
|
|
tsi_handshaker_destroy(handshaker_); |
|
|
|
|
tsi_handshaker_result_destroy(handshaker_result_); |
|
|
|
|
if (read_buffer_to_destroy_ != nullptr) { |
|
|
|
|
grpc_slice_buffer_destroy(read_buffer_to_destroy_); |
|
|
|
|
gpr_free(read_buffer_to_destroy_); |
|
|
|
|
} |
|
|
|
|
gpr_free(handshake_buffer_); |
|
|
|
|
grpc_slice_buffer_destroy(&outgoing_); |
|
|
|
|
auth_context_.reset(DEBUG_LOCATION, "handshake"); |
|
|
|
|
connector_.reset(DEBUG_LOCATION, "handshake"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
size_t SecurityHandshaker::MoveReadBufferIntoHandshakeBuffer() { |
|
|
|
|
size_t bytes_in_read_buffer = args_->read_buffer->length; |
|
|
|
|
size_t bytes_in_read_buffer = args_->read_buffer.Length(); |
|
|
|
|
if (handshake_buffer_size_ < bytes_in_read_buffer) { |
|
|
|
|
handshake_buffer_ = static_cast<uint8_t*>( |
|
|
|
|
gpr_realloc(handshake_buffer_, bytes_in_read_buffer)); |
|
|
|
|
handshake_buffer_size_ = bytes_in_read_buffer; |
|
|
|
|
} |
|
|
|
|
size_t offset = 0; |
|
|
|
|
while (args_->read_buffer->count > 0) { |
|
|
|
|
grpc_slice* next_slice = grpc_slice_buffer_peek_first(args_->read_buffer); |
|
|
|
|
memcpy(handshake_buffer_ + offset, GRPC_SLICE_START_PTR(*next_slice), |
|
|
|
|
GRPC_SLICE_LENGTH(*next_slice)); |
|
|
|
|
offset += GRPC_SLICE_LENGTH(*next_slice); |
|
|
|
|
grpc_slice_buffer_remove_first(args_->read_buffer); |
|
|
|
|
while (args_->read_buffer.Count() > 0) { |
|
|
|
|
Slice slice = args_->read_buffer.TakeFirst(); |
|
|
|
|
memcpy(handshake_buffer_ + offset, slice.data(), slice.size()); |
|
|
|
|
offset += slice.size(); |
|
|
|
|
} |
|
|
|
|
return bytes_in_read_buffer; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Set args_ fields to NULL, saving the endpoint and read buffer for
|
|
|
|
|
// later destruction.
|
|
|
|
|
void SecurityHandshaker::CleanupArgsForFailureLocked() { |
|
|
|
|
read_buffer_to_destroy_ = args_->read_buffer; |
|
|
|
|
args_->read_buffer = nullptr; |
|
|
|
|
args_->args = ChannelArgs(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// If the handshake failed or we're shutting down, clean up and invoke the
|
|
|
|
|
// callback with the error.
|
|
|
|
|
void SecurityHandshaker::HandshakeFailedLocked(grpc_error_handle error) { |
|
|
|
|
void SecurityHandshaker::HandshakeFailedLocked(absl::Status error) { |
|
|
|
|
if (error.ok()) { |
|
|
|
|
// If we were shut down after the handshake succeeded but before an
|
|
|
|
|
// endpoint callback was invoked, we need to generate our own error.
|
|
|
|
@ -200,17 +182,17 @@ void SecurityHandshaker::HandshakeFailedLocked(grpc_error_handle error) { |
|
|
|
|
} |
|
|
|
|
if (!is_shutdown_) { |
|
|
|
|
tsi_handshaker_shutdown(handshaker_); |
|
|
|
|
grpc_endpoint_destroy(args_->endpoint); |
|
|
|
|
args_->endpoint = nullptr; |
|
|
|
|
// Not shutting down, so the write failed. Clean up before
|
|
|
|
|
// invoking the callback.
|
|
|
|
|
CleanupArgsForFailureLocked(); |
|
|
|
|
// Set shutdown to true so that subsequent calls to
|
|
|
|
|
// security_handshaker_shutdown() do nothing.
|
|
|
|
|
is_shutdown_ = true; |
|
|
|
|
} |
|
|
|
|
// Invoke callback.
|
|
|
|
|
ExecCtx::Run(DEBUG_LOCATION, on_handshake_done_, error); |
|
|
|
|
Finish(std::move(error)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SecurityHandshaker::Finish(absl::Status status) { |
|
|
|
|
InvokeOnHandshakeDone(args_, std::move(on_handshake_done_), |
|
|
|
|
std::move(status)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
@ -306,19 +288,18 @@ void SecurityHandshaker::OnPeerCheckedInner(grpc_error_handle error) { |
|
|
|
|
grpc_slice slice = grpc_slice_from_copied_buffer( |
|
|
|
|
reinterpret_cast<const char*>(unused_bytes), unused_bytes_size); |
|
|
|
|
args_->endpoint = grpc_secure_endpoint_create( |
|
|
|
|
protector, zero_copy_protector, args_->endpoint, &slice, |
|
|
|
|
protector, zero_copy_protector, std::move(args_->endpoint), &slice, |
|
|
|
|
args_->args.ToC().get(), 1); |
|
|
|
|
CSliceUnref(slice); |
|
|
|
|
} else { |
|
|
|
|
args_->endpoint = grpc_secure_endpoint_create( |
|
|
|
|
protector, zero_copy_protector, args_->endpoint, nullptr, |
|
|
|
|
protector, zero_copy_protector, std::move(args_->endpoint), nullptr, |
|
|
|
|
args_->args.ToC().get(), 0); |
|
|
|
|
} |
|
|
|
|
} else if (unused_bytes_size > 0) { |
|
|
|
|
// Not wrapping the endpoint, so just pass along unused bytes.
|
|
|
|
|
grpc_slice slice = grpc_slice_from_copied_buffer( |
|
|
|
|
reinterpret_cast<const char*>(unused_bytes), unused_bytes_size); |
|
|
|
|
grpc_slice_buffer_add(args_->read_buffer, slice); |
|
|
|
|
args_->read_buffer.Append(Slice::FromCopiedBuffer( |
|
|
|
|
reinterpret_cast<const char*>(unused_bytes), unused_bytes_size)); |
|
|
|
|
} |
|
|
|
|
// Done with handshaker result.
|
|
|
|
|
tsi_handshaker_result_destroy(handshaker_result_); |
|
|
|
@ -329,11 +310,11 @@ void SecurityHandshaker::OnPeerCheckedInner(grpc_error_handle error) { |
|
|
|
|
args_->args = args_->args.SetObject( |
|
|
|
|
MakeChannelzSecurityFromAuthContext(auth_context_.get())); |
|
|
|
|
} |
|
|
|
|
// Invoke callback.
|
|
|
|
|
ExecCtx::Run(DEBUG_LOCATION, on_handshake_done_, absl::OkStatus()); |
|
|
|
|
// Set shutdown to true so that subsequent calls to
|
|
|
|
|
// security_handshaker_shutdown() do nothing.
|
|
|
|
|
is_shutdown_ = true; |
|
|
|
|
// Invoke callback.
|
|
|
|
|
Finish(absl::OkStatus()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SecurityHandshaker::OnPeerCheckedFn(void* arg, grpc_error_handle error) { |
|
|
|
@ -349,8 +330,8 @@ grpc_error_handle SecurityHandshaker::CheckPeerLocked() { |
|
|
|
|
return GRPC_ERROR_CREATE(absl::StrCat("Peer extraction failed (", |
|
|
|
|
tsi_result_to_string(result), ")")); |
|
|
|
|
} |
|
|
|
|
connector_->check_peer(peer, args_->endpoint, args_->args, &auth_context_, |
|
|
|
|
&on_peer_checked_); |
|
|
|
|
connector_->check_peer(peer, args_->endpoint.get(), args_->args, |
|
|
|
|
&auth_context_, &on_peer_checked_); |
|
|
|
|
grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( |
|
|
|
|
auth_context_.get(), GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME); |
|
|
|
|
const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it); |
|
|
|
@ -374,7 +355,7 @@ grpc_error_handle SecurityHandshaker::OnHandshakeNextDoneLocked( |
|
|
|
|
if (result == TSI_INCOMPLETE_DATA) { |
|
|
|
|
CHECK_EQ(bytes_to_send_size, 0u); |
|
|
|
|
grpc_endpoint_read( |
|
|
|
|
args_->endpoint, args_->read_buffer, |
|
|
|
|
args_->endpoint.get(), args_->read_buffer.c_slice_buffer(), |
|
|
|
|
GRPC_CLOSURE_INIT( |
|
|
|
|
&on_handshake_data_received_from_peer_, |
|
|
|
|
&SecurityHandshaker::OnHandshakeDataReceivedFromPeerFnScheduler, |
|
|
|
@ -388,6 +369,8 @@ grpc_error_handle SecurityHandshaker::OnHandshakeNextDoneLocked( |
|
|
|
|
if (security_connector != nullptr) { |
|
|
|
|
connector_type = security_connector->type().name(); |
|
|
|
|
} |
|
|
|
|
// TODO(roth): Get a better signal from the TSI layer as to what
|
|
|
|
|
// status code we should use here.
|
|
|
|
|
return GRPC_ERROR_CREATE(absl::StrCat( |
|
|
|
|
connector_type, " handshake failed (", tsi_result_to_string(result), |
|
|
|
|
")", (tsi_handshake_error_.empty() ? "" : ": "), tsi_handshake_error_)); |
|
|
|
@ -399,12 +382,11 @@ grpc_error_handle SecurityHandshaker::OnHandshakeNextDoneLocked( |
|
|
|
|
} |
|
|
|
|
if (bytes_to_send_size > 0) { |
|
|
|
|
// Send data to peer, if needed.
|
|
|
|
|
grpc_slice to_send = grpc_slice_from_copied_buffer( |
|
|
|
|
reinterpret_cast<const char*>(bytes_to_send), bytes_to_send_size); |
|
|
|
|
grpc_slice_buffer_reset_and_unref(&outgoing_); |
|
|
|
|
grpc_slice_buffer_add(&outgoing_, to_send); |
|
|
|
|
outgoing_.Clear(); |
|
|
|
|
outgoing_.Append(Slice::FromCopiedBuffer( |
|
|
|
|
reinterpret_cast<const char*>(bytes_to_send), bytes_to_send_size)); |
|
|
|
|
grpc_endpoint_write( |
|
|
|
|
args_->endpoint, &outgoing_, |
|
|
|
|
args_->endpoint.get(), outgoing_.c_slice_buffer(), |
|
|
|
|
GRPC_CLOSURE_INIT( |
|
|
|
|
&on_handshake_data_sent_to_peer_, |
|
|
|
|
&SecurityHandshaker::OnHandshakeDataSentToPeerFnScheduler, this, |
|
|
|
@ -413,7 +395,7 @@ grpc_error_handle SecurityHandshaker::OnHandshakeNextDoneLocked( |
|
|
|
|
} else if (handshaker_result == nullptr) { |
|
|
|
|
// There is nothing to send, but need to read from peer.
|
|
|
|
|
grpc_endpoint_read( |
|
|
|
|
args_->endpoint, args_->read_buffer, |
|
|
|
|
args_->endpoint.get(), args_->read_buffer.c_slice_buffer(), |
|
|
|
|
GRPC_CLOSURE_INIT( |
|
|
|
|
&on_handshake_data_received_from_peer_, |
|
|
|
|
&SecurityHandshaker::OnHandshakeDataReceivedFromPeerFnScheduler, |
|
|
|
@ -435,7 +417,7 @@ void SecurityHandshaker::OnHandshakeNextDoneGrpcWrapper( |
|
|
|
|
grpc_error_handle error = h->OnHandshakeNextDoneLocked( |
|
|
|
|
result, bytes_to_send, bytes_to_send_size, handshaker_result); |
|
|
|
|
if (!error.ok()) { |
|
|
|
|
h->HandshakeFailedLocked(error); |
|
|
|
|
h->HandshakeFailedLocked(std::move(error)); |
|
|
|
|
} else { |
|
|
|
|
h.release(); // Avoid unref
|
|
|
|
|
} |
|
|
|
@ -463,102 +445,102 @@ grpc_error_handle SecurityHandshaker::DoHandshakerNextLocked( |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This callback might be run inline while we are still holding on to the mutex,
|
|
|
|
|
// so schedule OnHandshakeDataReceivedFromPeerFn on ExecCtx to avoid a deadlock.
|
|
|
|
|
// so run OnHandshakeDataReceivedFromPeerFn asynchronously to avoid a deadlock.
|
|
|
|
|
// TODO(roth): This will no longer be necessary once we migrate to the
|
|
|
|
|
// EventEngine endpoint API.
|
|
|
|
|
void SecurityHandshaker::OnHandshakeDataReceivedFromPeerFnScheduler( |
|
|
|
|
void* arg, grpc_error_handle error) { |
|
|
|
|
SecurityHandshaker* h = static_cast<SecurityHandshaker*>(arg); |
|
|
|
|
ExecCtx::Run( |
|
|
|
|
DEBUG_LOCATION, |
|
|
|
|
GRPC_CLOSURE_INIT(&h->on_handshake_data_received_from_peer_, |
|
|
|
|
&SecurityHandshaker::OnHandshakeDataReceivedFromPeerFn, |
|
|
|
|
h, grpc_schedule_on_exec_ctx), |
|
|
|
|
error); |
|
|
|
|
SecurityHandshaker* handshaker = static_cast<SecurityHandshaker*>(arg); |
|
|
|
|
handshaker->args_->event_engine->Run( |
|
|
|
|
[handshaker, error = std::move(error)]() mutable { |
|
|
|
|
ApplicationCallbackExecCtx callback_exec_ctx; |
|
|
|
|
ExecCtx exec_ctx; |
|
|
|
|
handshaker->OnHandshakeDataReceivedFromPeerFn(std::move(error)); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SecurityHandshaker::OnHandshakeDataReceivedFromPeerFn( |
|
|
|
|
void* arg, grpc_error_handle error) { |
|
|
|
|
RefCountedPtr<SecurityHandshaker> h(static_cast<SecurityHandshaker*>(arg)); |
|
|
|
|
MutexLock lock(&h->mu_); |
|
|
|
|
if (!error.ok() || h->is_shutdown_) { |
|
|
|
|
h->HandshakeFailedLocked( |
|
|
|
|
void SecurityHandshaker::OnHandshakeDataReceivedFromPeerFn(absl::Status error) { |
|
|
|
|
RefCountedPtr<SecurityHandshaker> handshaker(this); |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
if (!error.ok() || is_shutdown_) { |
|
|
|
|
HandshakeFailedLocked( |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING("Handshake read failed", &error, 1)); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// Copy all slices received.
|
|
|
|
|
size_t bytes_received_size = h->MoveReadBufferIntoHandshakeBuffer(); |
|
|
|
|
size_t bytes_received_size = MoveReadBufferIntoHandshakeBuffer(); |
|
|
|
|
// Call TSI handshaker.
|
|
|
|
|
error = h->DoHandshakerNextLocked(h->handshake_buffer_, bytes_received_size); |
|
|
|
|
error = DoHandshakerNextLocked(handshake_buffer_, bytes_received_size); |
|
|
|
|
if (!error.ok()) { |
|
|
|
|
h->HandshakeFailedLocked(error); |
|
|
|
|
HandshakeFailedLocked(std::move(error)); |
|
|
|
|
} else { |
|
|
|
|
h.release(); // Avoid unref
|
|
|
|
|
handshaker.release(); // Avoid unref
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This callback might be run inline while we are still holding on to the mutex,
|
|
|
|
|
// so schedule OnHandshakeDataSentToPeerFn on ExecCtx to avoid a deadlock.
|
|
|
|
|
// so run OnHandshakeDataSentToPeerFn asynchronously to avoid a deadlock.
|
|
|
|
|
// TODO(roth): This will no longer be necessary once we migrate to the
|
|
|
|
|
// EventEngine endpoint API.
|
|
|
|
|
void SecurityHandshaker::OnHandshakeDataSentToPeerFnScheduler( |
|
|
|
|
void* arg, grpc_error_handle error) { |
|
|
|
|
SecurityHandshaker* h = static_cast<SecurityHandshaker*>(arg); |
|
|
|
|
ExecCtx::Run( |
|
|
|
|
DEBUG_LOCATION, |
|
|
|
|
GRPC_CLOSURE_INIT(&h->on_handshake_data_sent_to_peer_, |
|
|
|
|
&SecurityHandshaker::OnHandshakeDataSentToPeerFn, h, |
|
|
|
|
grpc_schedule_on_exec_ctx), |
|
|
|
|
error); |
|
|
|
|
SecurityHandshaker* handshaker = static_cast<SecurityHandshaker*>(arg); |
|
|
|
|
handshaker->args_->event_engine->Run( |
|
|
|
|
[handshaker, error = std::move(error)]() mutable { |
|
|
|
|
ApplicationCallbackExecCtx callback_exec_ctx; |
|
|
|
|
ExecCtx exec_ctx; |
|
|
|
|
handshaker->OnHandshakeDataSentToPeerFn(std::move(error)); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SecurityHandshaker::OnHandshakeDataSentToPeerFn(void* arg, |
|
|
|
|
grpc_error_handle error) { |
|
|
|
|
RefCountedPtr<SecurityHandshaker> h(static_cast<SecurityHandshaker*>(arg)); |
|
|
|
|
MutexLock lock(&h->mu_); |
|
|
|
|
if (!error.ok() || h->is_shutdown_) { |
|
|
|
|
h->HandshakeFailedLocked( |
|
|
|
|
void SecurityHandshaker::OnHandshakeDataSentToPeerFn(absl::Status error) { |
|
|
|
|
RefCountedPtr<SecurityHandshaker> handshaker(this); |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
if (!error.ok() || is_shutdown_) { |
|
|
|
|
HandshakeFailedLocked( |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING("Handshake write failed", &error, 1)); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// We may be done.
|
|
|
|
|
if (h->handshaker_result_ == nullptr) { |
|
|
|
|
if (handshaker_result_ == nullptr) { |
|
|
|
|
grpc_endpoint_read( |
|
|
|
|
h->args_->endpoint, h->args_->read_buffer, |
|
|
|
|
args_->endpoint.get(), args_->read_buffer.c_slice_buffer(), |
|
|
|
|
GRPC_CLOSURE_INIT( |
|
|
|
|
&h->on_handshake_data_received_from_peer_, |
|
|
|
|
&on_handshake_data_received_from_peer_, |
|
|
|
|
&SecurityHandshaker::OnHandshakeDataReceivedFromPeerFnScheduler, |
|
|
|
|
h.get(), grpc_schedule_on_exec_ctx), |
|
|
|
|
this, grpc_schedule_on_exec_ctx), |
|
|
|
|
/*urgent=*/true, /*min_progress_size=*/1); |
|
|
|
|
} else { |
|
|
|
|
error = h->CheckPeerLocked(); |
|
|
|
|
error = CheckPeerLocked(); |
|
|
|
|
if (!error.ok()) { |
|
|
|
|
h->HandshakeFailedLocked(error); |
|
|
|
|
HandshakeFailedLocked(error); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
h.release(); // Avoid unref
|
|
|
|
|
handshaker.release(); // Avoid unref
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// public handshaker API
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
void SecurityHandshaker::Shutdown(grpc_error_handle why) { |
|
|
|
|
void SecurityHandshaker::Shutdown(grpc_error_handle error) { |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
if (!is_shutdown_) { |
|
|
|
|
is_shutdown_ = true; |
|
|
|
|
connector_->cancel_check_peer(&on_peer_checked_, why); |
|
|
|
|
connector_->cancel_check_peer(&on_peer_checked_, std::move(error)); |
|
|
|
|
tsi_handshaker_shutdown(handshaker_); |
|
|
|
|
grpc_endpoint_destroy(args_->endpoint); |
|
|
|
|
args_->endpoint = nullptr; |
|
|
|
|
CleanupArgsForFailureLocked(); |
|
|
|
|
args_->endpoint.reset(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SecurityHandshaker::DoHandshake(grpc_tcp_server_acceptor* /*acceptor*/, |
|
|
|
|
grpc_closure* on_handshake_done, |
|
|
|
|
HandshakerArgs* args) { |
|
|
|
|
void SecurityHandshaker::DoHandshake( |
|
|
|
|
HandshakerArgs* args, |
|
|
|
|
absl::AnyInvocable<void(absl::Status)> on_handshake_done) { |
|
|
|
|
auto ref = Ref(); |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
args_ = args; |
|
|
|
|
on_handshake_done_ = on_handshake_done; |
|
|
|
|
on_handshake_done_ = std::move(on_handshake_done); |
|
|
|
|
size_t bytes_received_size = MoveReadBufferIntoHandshakeBuffer(); |
|
|
|
|
grpc_error_handle error = |
|
|
|
|
DoHandshakerNextLocked(handshake_buffer_, bytes_received_size); |
|
|
|
@ -576,19 +558,13 @@ void SecurityHandshaker::DoHandshake(grpc_tcp_server_acceptor* /*acceptor*/, |
|
|
|
|
class FailHandshaker : public Handshaker { |
|
|
|
|
public: |
|
|
|
|
explicit FailHandshaker(absl::Status status) : status_(std::move(status)) {} |
|
|
|
|
const char* name() const override { return "security_fail"; } |
|
|
|
|
void Shutdown(grpc_error_handle /*why*/) override {} |
|
|
|
|
void DoHandshake(grpc_tcp_server_acceptor* /*acceptor*/, |
|
|
|
|
grpc_closure* on_handshake_done, |
|
|
|
|
HandshakerArgs* args) override { |
|
|
|
|
grpc_endpoint_destroy(args->endpoint); |
|
|
|
|
args->endpoint = nullptr; |
|
|
|
|
args->args = ChannelArgs(); |
|
|
|
|
grpc_slice_buffer_destroy(args->read_buffer); |
|
|
|
|
gpr_free(args->read_buffer); |
|
|
|
|
args->read_buffer = nullptr; |
|
|
|
|
ExecCtx::Run(DEBUG_LOCATION, on_handshake_done, status_); |
|
|
|
|
absl::string_view name() const override { return "security_fail"; } |
|
|
|
|
void DoHandshake( |
|
|
|
|
HandshakerArgs* args, |
|
|
|
|
absl::AnyInvocable<void(absl::Status)> on_handshake_done) override { |
|
|
|
|
InvokeOnHandshakeDone(args, std::move(on_handshake_done), status_); |
|
|
|
|
} |
|
|
|
|
void Shutdown(absl::Status /*error*/) override {} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
~FailHandshaker() override = default; |
|
|
|
|