|
|
|
@ -88,7 +88,7 @@ class WSAErrorContext { |
|
|
|
|
* from c-ares and are used with the grpc windows poller, and it, e.g., |
|
|
|
|
* manufactures virtual socket error codes when it e.g. needs to tell the c-ares |
|
|
|
|
* library to wait for an async read. */ |
|
|
|
|
class GrpcPolledFdWindows : public GrpcPolledFd { |
|
|
|
|
class GrpcPolledFdWindows { |
|
|
|
|
public: |
|
|
|
|
enum WriteState { |
|
|
|
|
WRITE_IDLE, |
|
|
|
@ -146,7 +146,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { |
|
|
|
|
write_closure_ = nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RegisterForOnReadableLocked(grpc_closure* read_closure) override { |
|
|
|
|
void RegisterForOnReadableLocked(grpc_closure* read_closure) { |
|
|
|
|
GPR_ASSERT(read_closure_ == nullptr); |
|
|
|
|
read_closure_ = read_closure; |
|
|
|
|
GPR_ASSERT(GRPC_SLICE_LENGTH(read_buf_) == 0); |
|
|
|
@ -206,7 +206,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { |
|
|
|
|
grpc_socket_notify_on_read(winsocket_, &outer_read_closure_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RegisterForOnWriteableLocked(grpc_closure* write_closure) override { |
|
|
|
|
void RegisterForOnWriteableLocked(grpc_closure* write_closure) { |
|
|
|
|
if (socket_type_ == SOCK_DGRAM) { |
|
|
|
|
GRPC_CARES_TRACE_LOG("fd:|%s| RegisterForOnWriteableLocked called", |
|
|
|
|
GetName()); |
|
|
|
@ -272,19 +272,17 @@ class GrpcPolledFdWindows : public GrpcPolledFd { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool IsFdStillReadableLocked() override { |
|
|
|
|
return GRPC_SLICE_LENGTH(read_buf_) > 0; |
|
|
|
|
} |
|
|
|
|
bool IsFdStillReadableLocked() { return GRPC_SLICE_LENGTH(read_buf_) > 0; } |
|
|
|
|
|
|
|
|
|
void ShutdownLocked(grpc_error* error) override { |
|
|
|
|
void ShutdownLocked(grpc_error* error) { |
|
|
|
|
grpc_winsocket_shutdown(winsocket_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ares_socket_t GetWrappedAresSocketLocked() override { |
|
|
|
|
ares_socket_t GetWrappedAresSocketLocked() { |
|
|
|
|
return grpc_winsocket_wrapped_socket(winsocket_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const char* GetName() override { return name_; } |
|
|
|
|
const char* GetName() { return name_; } |
|
|
|
|
|
|
|
|
|
ares_ssize_t RecvFrom(WSAErrorContext* wsa_error_ctx, void* data, |
|
|
|
|
ares_socket_t data_len, int flags, |
|
|
|
@ -816,14 +814,19 @@ class SockToPolledFdMap { |
|
|
|
|
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data); |
|
|
|
|
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(s); |
|
|
|
|
map->RemoveEntry(s); |
|
|
|
|
// See https://github.com/grpc/grpc/pull/20284, this trace log is
|
|
|
|
|
// intentionally placed to attempt to trigger a crash in case of a
|
|
|
|
|
// use after free on polled_fd.
|
|
|
|
|
GRPC_CARES_TRACE_LOG("CloseSocket called for socket: %s", |
|
|
|
|
polled_fd->GetName()); |
|
|
|
|
// If a gRPC polled fd has not made it in to the driver's list yet, then
|
|
|
|
|
// the driver has not and will never see this socket.
|
|
|
|
|
if (!polled_fd->gotten_into_driver_list()) { |
|
|
|
|
polled_fd->ShutdownLocked(GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"Shut down c-ares fd before without it ever having made it into the " |
|
|
|
|
"driver's list")); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
grpc_core::Delete(polled_fd); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -840,6 +843,42 @@ const struct ares_socket_functions custom_ares_sock_funcs = { |
|
|
|
|
&SockToPolledFdMap::SendV /* sendv */, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* A thin wrapper over a GrpcPolledFdWindows object but with a shorter
|
|
|
|
|
lifetime. This object releases it's GrpcPolledFdWindows upon destruction, |
|
|
|
|
so that c-ares can close it via usual socket teardown. */ |
|
|
|
|
class GrpcPolledFdWindowsWrapper : public GrpcPolledFd { |
|
|
|
|
public: |
|
|
|
|
GrpcPolledFdWindowsWrapper(GrpcPolledFdWindows* wrapped) |
|
|
|
|
: wrapped_(wrapped) {} |
|
|
|
|
|
|
|
|
|
~GrpcPolledFdWindowsWrapper() {} |
|
|
|
|
|
|
|
|
|
void RegisterForOnReadableLocked(grpc_closure* read_closure) override { |
|
|
|
|
wrapped_->RegisterForOnReadableLocked(read_closure); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RegisterForOnWriteableLocked(grpc_closure* write_closure) override { |
|
|
|
|
wrapped_->RegisterForOnWriteableLocked(write_closure); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool IsFdStillReadableLocked() override { |
|
|
|
|
return wrapped_->IsFdStillReadableLocked(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ShutdownLocked(grpc_error* error) override { |
|
|
|
|
wrapped_->ShutdownLocked(error); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ares_socket_t GetWrappedAresSocketLocked() override { |
|
|
|
|
return wrapped_->GetWrappedAresSocketLocked(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const char* GetName() override { return wrapped_->GetName(); } |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
GrpcPolledFdWindows* wrapped_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class GrpcPolledFdFactoryWindows : public GrpcPolledFdFactory { |
|
|
|
|
public: |
|
|
|
|
GrpcPolledFdFactoryWindows(grpc_combiner* combiner) |
|
|
|
@ -852,7 +891,7 @@ class GrpcPolledFdFactoryWindows : public GrpcPolledFdFactory { |
|
|
|
|
// Set a flag so that the virtual socket "close" method knows it
|
|
|
|
|
// doesn't need to call ShutdownLocked, since now the driver will.
|
|
|
|
|
polled_fd->set_gotten_into_driver_list(); |
|
|
|
|
return polled_fd; |
|
|
|
|
return grpc_core::New<GrpcPolledFdWindowsWrapper>(polled_fd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ConfigureAresChannelLocked(ares_channel channel) override { |
|
|
|
|