grpc 1.22.0 → 1.23.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +487 -649
- data/include/grpc/grpc_security.h +25 -0
- data/include/grpc/impl/codegen/grpc_types.h +11 -2
- data/include/grpc/impl/codegen/port_platform.h +12 -0
- data/src/core/ext/filters/client_channel/backup_poller.cc +4 -2
- data/src/core/ext/filters/client_channel/client_channel.cc +477 -182
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +25 -16
- data/src/core/ext/filters/client_channel/client_channel_channelz.h +11 -6
- data/src/core/ext/filters/client_channel/connector.h +10 -2
- data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -3
- data/src/core/ext/filters/client_channel/http_proxy.cc +9 -10
- data/src/core/ext/filters/client_channel/lb_policy.cc +2 -17
- data/src/core/ext/filters/client_channel/lb_policy.h +36 -8
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +22 -8
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +86 -52
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +7 -0
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +73 -72
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +8 -12
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +25 -101
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +5 -5
- data/src/core/ext/filters/client_channel/parse_address.cc +29 -26
- data/src/core/ext/filters/client_channel/resolver.h +3 -11
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +5 -3
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +405 -82
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +44 -51
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +0 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +0 -1
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +11 -6
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +130 -65
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +8 -3
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +31 -14
- data/src/core/ext/filters/client_channel/resolver_factory.h +4 -0
- data/src/core/ext/filters/client_channel/resolver_registry.cc +11 -0
- data/src/core/ext/filters/client_channel/resolver_registry.h +3 -0
- data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +10 -49
- data/src/core/ext/filters/client_channel/resolving_lb_policy.h +1 -14
- data/src/core/ext/filters/client_channel/retry_throttle.h +2 -3
- data/src/core/ext/filters/client_channel/subchannel.cc +65 -58
- data/src/core/ext/filters/client_channel/subchannel.h +65 -45
- data/src/core/ext/filters/client_channel/subchannel_interface.h +15 -30
- data/src/core/ext/filters/client_idle/client_idle_filter.cc +262 -0
- data/src/core/ext/filters/http/client/http_client_filter.cc +4 -5
- data/src/core/ext/filters/http/client_authority_filter.cc +2 -2
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +140 -152
- data/src/core/ext/filters/max_age/max_age_filter.cc +3 -3
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +3 -4
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +7 -6
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +63 -38
- data/src/core/ext/transport/chttp2/transport/context_list.cc +3 -1
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -4
- data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -0
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +8 -0
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +7 -0
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +1 -0
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +37 -22
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +136 -81
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -0
- data/src/core/ext/transport/chttp2/transport/hpack_table.cc +7 -166
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +41 -15
- data/src/core/ext/transport/chttp2/transport/internal.h +13 -2
- data/src/core/ext/transport/chttp2/transport/parsing.cc +35 -22
- data/src/core/ext/transport/chttp2/transport/stream_map.cc +28 -18
- data/src/core/ext/transport/chttp2/transport/writing.cc +1 -0
- data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
- data/src/core/lib/channel/channelz.cc +80 -33
- data/src/core/lib/channel/channelz.h +28 -13
- data/src/core/lib/compression/compression.cc +1 -2
- data/src/core/lib/compression/compression_args.cc +13 -6
- data/src/core/lib/compression/compression_args.h +3 -2
- data/src/core/lib/compression/compression_internal.cc +1 -1
- data/src/core/lib/gpr/env_linux.cc +10 -21
- data/src/core/lib/gpr/env_posix.cc +0 -5
- data/src/core/lib/gpr/string.cc +7 -2
- data/src/core/lib/gpr/string.h +1 -0
- data/src/core/lib/gpr/sync_posix.cc +0 -129
- data/src/core/lib/gprpp/debug_location.h +3 -2
- data/src/core/lib/gprpp/fork.cc +14 -21
- data/src/core/lib/gprpp/fork.h +15 -4
- data/src/core/lib/gprpp/host_port.cc +118 -0
- data/src/core/lib/{gpr → gprpp}/host_port.h +27 -11
- data/src/core/lib/gprpp/map.h +25 -0
- data/src/core/lib/gprpp/memory.h +26 -9
- data/src/core/lib/gprpp/ref_counted.h +63 -21
- data/src/core/lib/gprpp/string_view.h +143 -0
- data/src/core/lib/gprpp/thd.h +10 -1
- data/src/core/lib/gprpp/thd_posix.cc +25 -0
- data/src/core/lib/gprpp/thd_windows.cc +9 -1
- data/src/core/lib/http/httpcli_security_connector.cc +3 -1
- data/src/core/lib/iomgr/cfstream_handle.cc +6 -1
- data/src/core/lib/iomgr/cfstream_handle.h +8 -2
- data/src/core/lib/iomgr/combiner.cc +4 -4
- data/src/core/lib/iomgr/error.cc +18 -8
- data/src/core/lib/iomgr/error.h +2 -0
- data/src/core/lib/iomgr/ev_posix.cc +4 -2
- data/src/core/lib/iomgr/executor.cc +4 -1
- data/src/core/lib/iomgr/executor/mpmcqueue.cc +183 -0
- data/src/core/lib/iomgr/executor/mpmcqueue.h +178 -0
- data/src/core/lib/iomgr/executor/threadpool.cc +138 -0
- data/src/core/lib/iomgr/executor/threadpool.h +153 -0
- data/src/core/lib/iomgr/fork_posix.cc +4 -2
- data/src/core/lib/iomgr/iocp_windows.cc +2 -2
- data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +14 -0
- data/src/core/lib/iomgr/iomgr_uv.cc +3 -0
- data/src/core/lib/iomgr/lockfree_event.cc +3 -3
- data/src/core/lib/iomgr/resolve_address_custom.cc +16 -20
- data/src/core/lib/iomgr/resolve_address_posix.cc +8 -10
- data/src/core/lib/iomgr/resolve_address_windows.cc +6 -8
- data/src/core/lib/iomgr/sockaddr_utils.cc +5 -3
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +0 -1
- data/src/core/lib/iomgr/socket_windows.h +1 -1
- data/src/core/lib/iomgr/tcp_client_cfstream.cc +7 -6
- data/src/core/lib/iomgr/tcp_client_custom.cc +1 -0
- data/src/core/lib/iomgr/tcp_custom.cc +4 -0
- data/src/core/lib/iomgr/tcp_posix.cc +8 -2
- data/src/core/lib/iomgr/tcp_server_custom.cc +1 -0
- data/src/core/lib/iomgr/tcp_server_windows.cc +1 -1
- data/src/core/lib/iomgr/tcp_windows.cc +7 -7
- data/src/core/lib/iomgr/timer_custom.cc +1 -0
- data/src/core/lib/iomgr/timer_manager.cc +0 -29
- data/src/core/lib/security/credentials/credentials.cc +84 -0
- data/src/core/lib/security/credentials/credentials.h +58 -2
- data/src/core/lib/security/credentials/jwt/json_token.cc +6 -2
- data/src/core/lib/security/credentials/jwt/json_token.h +1 -1
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +245 -24
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +16 -0
- data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +3 -2
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +21 -25
- data/src/core/lib/security/security_connector/local/local_security_connector.cc +3 -2
- data/src/core/lib/security/security_connector/security_connector.cc +1 -1
- data/src/core/lib/security/security_connector/security_connector.h +1 -1
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +19 -19
- data/src/core/lib/security/security_connector/ssl_utils.cc +26 -31
- data/src/core/lib/security/security_connector/ssl_utils.h +11 -8
- data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +16 -20
- data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +4 -3
- data/src/core/lib/security/transport/client_auth_filter.cc +1 -2
- data/src/core/lib/security/util/json_util.cc +19 -5
- data/src/core/lib/security/util/json_util.h +3 -1
- data/src/core/lib/slice/slice.cc +69 -50
- data/src/core/lib/slice/slice_buffer.cc +6 -5
- data/src/core/lib/slice/slice_hash_table.h +3 -7
- data/src/core/lib/slice/slice_intern.cc +130 -39
- data/src/core/lib/slice/slice_internal.h +8 -0
- data/src/core/lib/slice/slice_utils.h +120 -0
- data/src/core/lib/slice/slice_weak_hash_table.h +2 -7
- data/src/core/lib/surface/call.cc +8 -3
- data/src/core/lib/surface/channel.cc +31 -8
- data/src/core/lib/surface/completion_queue.cc +17 -7
- data/src/core/lib/surface/init_secure.cc +4 -1
- data/src/core/lib/surface/lame_client.cc +2 -2
- data/src/core/lib/surface/server.cc +34 -35
- data/src/core/lib/surface/server.h +8 -17
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/lib/transport/byte_stream.cc +3 -5
- data/src/core/lib/transport/byte_stream.h +1 -2
- data/src/core/lib/transport/error_utils.cc +10 -1
- data/src/core/lib/transport/metadata.cc +202 -35
- data/src/core/lib/transport/metadata.h +81 -6
- data/src/core/lib/transport/static_metadata.cc +1257 -465
- data/src/core/lib/transport/static_metadata.h +190 -347
- data/src/core/lib/transport/timeout_encoding.cc +7 -0
- data/src/core/lib/transport/timeout_encoding.h +3 -2
- data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +0 -1
- data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -7
- data/src/core/tsi/ssl_transport_security.cc +35 -43
- data/src/core/tsi/ssl_transport_security.h +2 -1
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
- data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
- data/src/ruby/lib/grpc/grpc.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +39 -33
- data/src/core/lib/gpr/host_port.cc +0 -98
@@ -84,7 +84,6 @@
|
|
84
84
|
#include "src/core/lib/backoff/backoff.h"
|
85
85
|
#include "src/core/lib/channel/channel_args.h"
|
86
86
|
#include "src/core/lib/channel/channel_stack.h"
|
87
|
-
#include "src/core/lib/gpr/host_port.h"
|
88
87
|
#include "src/core/lib/gpr/string.h"
|
89
88
|
#include "src/core/lib/gprpp/manual_constructor.h"
|
90
89
|
#include "src/core/lib/gprpp/map.h"
|
@@ -185,9 +184,7 @@ class XdsLb : public LoadBalancingPolicy {
|
|
185
184
|
bool seen_initial_response() const { return seen_initial_response_; }
|
186
185
|
|
187
186
|
private:
|
188
|
-
|
189
|
-
template <typename T>
|
190
|
-
friend void grpc_core::Delete(T*);
|
187
|
+
GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
|
191
188
|
|
192
189
|
~BalancerCallState();
|
193
190
|
|
@@ -570,7 +567,7 @@ XdsLb::PickResult XdsLb::Picker::Pick(PickArgs args) {
|
|
570
567
|
PickResult result = PickFromLocality(key, args);
|
571
568
|
// If pick succeeded, add client stats.
|
572
569
|
if (result.type == PickResult::PICK_COMPLETE &&
|
573
|
-
result.
|
570
|
+
result.subchannel != nullptr && client_stats_ != nullptr) {
|
574
571
|
// TODO(roth): Add support for client stats.
|
575
572
|
}
|
576
573
|
return result;
|
@@ -1989,6 +1986,9 @@ void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() {
|
|
1989
1986
|
parent_->interested_parties());
|
1990
1987
|
pending_child_policy_.reset();
|
1991
1988
|
}
|
1989
|
+
// Drop our ref to the child's picker, in case it's holding a ref to
|
1990
|
+
// the child.
|
1991
|
+
picker_ref_.reset();
|
1992
1992
|
}
|
1993
1993
|
|
1994
1994
|
void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() {
|
@@ -33,8 +33,8 @@
|
|
33
33
|
#include <grpc/support/log.h>
|
34
34
|
#include <grpc/support/string_util.h>
|
35
35
|
|
36
|
-
#include "src/core/lib/gpr/host_port.h"
|
37
36
|
#include "src/core/lib/gpr/string.h"
|
37
|
+
#include "src/core/lib/gprpp/host_port.h"
|
38
38
|
|
39
39
|
#ifdef GRPC_POSIX_SOCKET
|
40
40
|
#include <errno.h>
|
@@ -73,9 +73,9 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
|
|
73
73
|
bool log_errors) {
|
74
74
|
bool success = false;
|
75
75
|
// Split host and port.
|
76
|
-
char
|
77
|
-
char
|
78
|
-
if (!
|
76
|
+
grpc_core::UniquePtr<char> host;
|
77
|
+
grpc_core::UniquePtr<char> port;
|
78
|
+
if (!grpc_core::SplitHostPort(hostport, &host, &port)) {
|
79
79
|
if (log_errors) {
|
80
80
|
gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport);
|
81
81
|
}
|
@@ -86,8 +86,10 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
|
|
86
86
|
addr->len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in));
|
87
87
|
grpc_sockaddr_in* in = reinterpret_cast<grpc_sockaddr_in*>(addr->addr);
|
88
88
|
in->sin_family = GRPC_AF_INET;
|
89
|
-
if (grpc_inet_pton(GRPC_AF_INET, host, &in->sin_addr) == 0) {
|
90
|
-
if (log_errors)
|
89
|
+
if (grpc_inet_pton(GRPC_AF_INET, host.get(), &in->sin_addr) == 0) {
|
90
|
+
if (log_errors) {
|
91
|
+
gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host.get());
|
92
|
+
}
|
91
93
|
goto done;
|
92
94
|
}
|
93
95
|
// Parse port.
|
@@ -96,15 +98,14 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
|
|
96
98
|
goto done;
|
97
99
|
}
|
98
100
|
int port_num;
|
99
|
-
if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
|
100
|
-
|
101
|
+
if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 ||
|
102
|
+
port_num > 65535) {
|
103
|
+
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port.get());
|
101
104
|
goto done;
|
102
105
|
}
|
103
106
|
in->sin_port = grpc_htons(static_cast<uint16_t>(port_num));
|
104
107
|
success = true;
|
105
108
|
done:
|
106
|
-
gpr_free(host);
|
107
|
-
gpr_free(port);
|
108
109
|
return success;
|
109
110
|
}
|
110
111
|
|
@@ -124,9 +125,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
|
|
124
125
|
bool log_errors) {
|
125
126
|
bool success = false;
|
126
127
|
// Split host and port.
|
127
|
-
char
|
128
|
-
char
|
129
|
-
if (!
|
128
|
+
grpc_core::UniquePtr<char> host;
|
129
|
+
grpc_core::UniquePtr<char> port;
|
130
|
+
if (!grpc_core::SplitHostPort(hostport, &host, &port)) {
|
130
131
|
if (log_errors) {
|
131
132
|
gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport);
|
132
133
|
}
|
@@ -138,11 +139,12 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
|
|
138
139
|
grpc_sockaddr_in6* in6 = reinterpret_cast<grpc_sockaddr_in6*>(addr->addr);
|
139
140
|
in6->sin6_family = GRPC_AF_INET6;
|
140
141
|
// Handle the RFC6874 syntax for IPv6 zone identifiers.
|
141
|
-
char* host_end =
|
142
|
+
char* host_end =
|
143
|
+
static_cast<char*>(gpr_memrchr(host.get(), '%', strlen(host.get())));
|
142
144
|
if (host_end != nullptr) {
|
143
|
-
GPR_ASSERT(host_end >= host);
|
145
|
+
GPR_ASSERT(host_end >= host.get());
|
144
146
|
char host_without_scope[GRPC_INET6_ADDRSTRLEN + 1];
|
145
|
-
size_t host_without_scope_len = static_cast<size_t>(host_end - host);
|
147
|
+
size_t host_without_scope_len = static_cast<size_t>(host_end - host.get());
|
146
148
|
uint32_t sin6_scope_id = 0;
|
147
149
|
if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) {
|
148
150
|
if (log_errors) {
|
@@ -154,7 +156,7 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
|
|
154
156
|
}
|
155
157
|
goto done;
|
156
158
|
}
|
157
|
-
strncpy(host_without_scope, host, host_without_scope_len);
|
159
|
+
strncpy(host_without_scope, host.get(), host_without_scope_len);
|
158
160
|
host_without_scope[host_without_scope_len] = '\0';
|
159
161
|
if (grpc_inet_pton(GRPC_AF_INET6, host_without_scope, &in6->sin6_addr) ==
|
160
162
|
0) {
|
@@ -163,9 +165,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
|
|
163
165
|
}
|
164
166
|
goto done;
|
165
167
|
}
|
166
|
-
if (gpr_parse_bytes_to_uint32(
|
167
|
-
|
168
|
-
|
168
|
+
if (gpr_parse_bytes_to_uint32(
|
169
|
+
host_end + 1, strlen(host.get()) - host_without_scope_len - 1,
|
170
|
+
&sin6_scope_id) == 0) {
|
169
171
|
if ((sin6_scope_id = grpc_if_nametoindex(host_end + 1)) == 0) {
|
170
172
|
gpr_log(GPR_ERROR,
|
171
173
|
"Invalid interface name: '%s'. "
|
@@ -177,8 +179,10 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
|
|
177
179
|
// Handle "sin6_scope_id" being type "u_long". See grpc issue #10027.
|
178
180
|
in6->sin6_scope_id = sin6_scope_id;
|
179
181
|
} else {
|
180
|
-
if (grpc_inet_pton(GRPC_AF_INET6, host, &in6->sin6_addr) == 0) {
|
181
|
-
if (log_errors)
|
182
|
+
if (grpc_inet_pton(GRPC_AF_INET6, host.get(), &in6->sin6_addr) == 0) {
|
183
|
+
if (log_errors) {
|
184
|
+
gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host.get());
|
185
|
+
}
|
182
186
|
goto done;
|
183
187
|
}
|
184
188
|
}
|
@@ -188,15 +192,14 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
|
|
188
192
|
goto done;
|
189
193
|
}
|
190
194
|
int port_num;
|
191
|
-
if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
|
192
|
-
|
195
|
+
if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 ||
|
196
|
+
port_num > 65535) {
|
197
|
+
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port.get());
|
193
198
|
goto done;
|
194
199
|
}
|
195
200
|
in6->sin6_port = grpc_htons(static_cast<uint16_t>(port_num));
|
196
201
|
success = true;
|
197
202
|
done:
|
198
|
-
gpr_free(host);
|
199
|
-
gpr_free(port);
|
200
203
|
return success;
|
201
204
|
}
|
202
205
|
|
@@ -117,12 +117,10 @@ class Resolver : public InternallyRefCounted<Resolver> {
|
|
117
117
|
/// implementations. At that point, this method can go away.
|
118
118
|
virtual void ResetBackoffLocked() {}
|
119
119
|
|
120
|
+
// Note: This must be invoked while holding the combiner.
|
120
121
|
void Orphan() override {
|
121
|
-
|
122
|
-
|
123
|
-
GRPC_CLOSURE_CREATE(&Resolver::ShutdownAndUnrefLocked, this,
|
124
|
-
grpc_combiner_scheduler(combiner_)),
|
125
|
-
GRPC_ERROR_NONE);
|
122
|
+
ShutdownLocked();
|
123
|
+
Unref();
|
126
124
|
}
|
127
125
|
|
128
126
|
GRPC_ABSTRACT_BASE_CLASS
|
@@ -147,12 +145,6 @@ class Resolver : public InternallyRefCounted<Resolver> {
|
|
147
145
|
ResultHandler* result_handler() const { return result_handler_.get(); }
|
148
146
|
|
149
147
|
private:
|
150
|
-
static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) {
|
151
|
-
Resolver* resolver = static_cast<Resolver*>(arg);
|
152
|
-
resolver->ShutdownLocked();
|
153
|
-
resolver->Unref();
|
154
|
-
}
|
155
|
-
|
156
148
|
UniquePtr<ResultHandler> result_handler_;
|
157
149
|
grpc_combiner* combiner_;
|
158
150
|
};
|
@@ -38,7 +38,6 @@
|
|
38
38
|
#include "src/core/ext/filters/client_channel/service_config.h"
|
39
39
|
#include "src/core/lib/backoff/backoff.h"
|
40
40
|
#include "src/core/lib/channel/channel_args.h"
|
41
|
-
#include "src/core/lib/gpr/host_port.h"
|
42
41
|
#include "src/core/lib/gpr/string.h"
|
43
42
|
#include "src/core/lib/gprpp/manual_constructor.h"
|
44
43
|
#include "src/core/lib/iomgr/combiner.h"
|
@@ -145,7 +144,7 @@ AresDnsResolver::AresDnsResolver(ResolverArgs args)
|
|
145
144
|
arg = grpc_channel_args_find(channel_args_,
|
146
145
|
GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
|
147
146
|
min_time_between_resolutions_ =
|
148
|
-
grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX});
|
147
|
+
grpc_channel_arg_get_integer(arg, {1000 * 30, 0, INT_MAX});
|
149
148
|
// Enable SRV queries option
|
150
149
|
arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ENABLE_SRV_QUERIES);
|
151
150
|
enable_srv_queries_ = grpc_channel_arg_get_bool(arg, false);
|
@@ -401,7 +400,8 @@ void AresDnsResolver::MaybeStartResolvingLocked() {
|
|
401
400
|
// new closure API is done, find a way to track this ref with the timer
|
402
401
|
// callback as part of the type system.
|
403
402
|
Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release();
|
404
|
-
grpc_timer_init(&next_resolution_timer_,
|
403
|
+
grpc_timer_init(&next_resolution_timer_,
|
404
|
+
ExecCtx::Get()->Now() + ms_until_next_resolution,
|
405
405
|
&on_next_resolution_);
|
406
406
|
return;
|
407
407
|
}
|
@@ -433,6 +433,8 @@ void AresDnsResolver::StartResolvingLocked() {
|
|
433
433
|
|
434
434
|
class AresDnsResolverFactory : public ResolverFactory {
|
435
435
|
public:
|
436
|
+
bool IsValidUri(const grpc_uri* uri) const override { return true; }
|
437
|
+
|
436
438
|
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
|
437
439
|
return OrphanablePtr<Resolver>(New<AresDnsResolver>(std::move(args)));
|
438
440
|
}
|
@@ -31,6 +31,9 @@
|
|
31
31
|
#include "src/core/lib/gpr/string.h"
|
32
32
|
#include "src/core/lib/gprpp/memory.h"
|
33
33
|
#include "src/core/lib/iomgr/combiner.h"
|
34
|
+
#include "src/core/lib/iomgr/iocp_windows.h"
|
35
|
+
#include "src/core/lib/iomgr/sockaddr_utils.h"
|
36
|
+
#include "src/core/lib/iomgr/sockaddr_windows.h"
|
34
37
|
#include "src/core/lib/iomgr/socket_windows.h"
|
35
38
|
#include "src/core/lib/iomgr/tcp_windows.h"
|
36
39
|
#include "src/core/lib/slice/slice_internal.h"
|
@@ -50,6 +53,32 @@ struct iovec {
|
|
50
53
|
|
51
54
|
namespace grpc_core {
|
52
55
|
|
56
|
+
/* c-ares reads and takes action on the error codes of the
|
57
|
+
* "virtual socket operations" in this file, via the WSAGetLastError
|
58
|
+
* APIs. If code in this file wants to set a specific WSA error that
|
59
|
+
* c-ares should read, it must do so by calling SetWSAError() on the
|
60
|
+
* WSAErrorContext instance passed to it. A WSAErrorContext must only be
|
61
|
+
* instantiated at the top of the virtual socket function callstack. */
|
62
|
+
class WSAErrorContext {
|
63
|
+
public:
|
64
|
+
explicit WSAErrorContext(){};
|
65
|
+
|
66
|
+
~WSAErrorContext() {
|
67
|
+
if (error_ != 0) {
|
68
|
+
WSASetLastError(error_);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
/* Disallow copy and assignment operators */
|
73
|
+
WSAErrorContext(const WSAErrorContext&) = delete;
|
74
|
+
WSAErrorContext& operator=(const WSAErrorContext&) = delete;
|
75
|
+
|
76
|
+
void SetWSAError(int error) { error_ = error; }
|
77
|
+
|
78
|
+
private:
|
79
|
+
int error_ = 0;
|
80
|
+
};
|
81
|
+
|
53
82
|
/* c-ares creates its own sockets and is meant to read them when readable and
|
54
83
|
* write them when writeable. To fit this socket usage model into the grpc
|
55
84
|
* windows poller (which gives notifications when attempted reads and writes are
|
@@ -68,11 +97,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
68
97
|
WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY,
|
69
98
|
};
|
70
99
|
|
71
|
-
GrpcPolledFdWindows(ares_socket_t as, grpc_combiner* combiner
|
100
|
+
GrpcPolledFdWindows(ares_socket_t as, grpc_combiner* combiner,
|
101
|
+
int address_family, int socket_type)
|
72
102
|
: read_buf_(grpc_empty_slice()),
|
73
103
|
write_buf_(grpc_empty_slice()),
|
74
|
-
|
75
|
-
gotten_into_driver_list_(false)
|
104
|
+
tcp_write_state_(WRITE_IDLE),
|
105
|
+
gotten_into_driver_list_(false),
|
106
|
+
address_family_(address_family),
|
107
|
+
socket_type_(socket_type) {
|
76
108
|
gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, as);
|
77
109
|
winsocket_ = grpc_winsocket_create(as, name_);
|
78
110
|
combiner_ = GRPC_COMBINER_REF(combiner, name_);
|
@@ -82,6 +114,16 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
82
114
|
GRPC_CLOSURE_INIT(&outer_write_closure_,
|
83
115
|
&GrpcPolledFdWindows::OnIocpWriteable, this,
|
84
116
|
grpc_combiner_scheduler(combiner_));
|
117
|
+
GRPC_CLOSURE_INIT(&on_tcp_connect_locked_,
|
118
|
+
&GrpcPolledFdWindows::OnTcpConnectLocked, this,
|
119
|
+
grpc_combiner_scheduler(combiner_));
|
120
|
+
GRPC_CLOSURE_INIT(&continue_register_for_on_readable_locked_,
|
121
|
+
&GrpcPolledFdWindows::ContinueRegisterForOnReadableLocked,
|
122
|
+
this, grpc_combiner_scheduler(combiner_));
|
123
|
+
GRPC_CLOSURE_INIT(
|
124
|
+
&continue_register_for_on_writeable_locked_,
|
125
|
+
&GrpcPolledFdWindows::ContinueRegisterForOnWriteableLocked, this,
|
126
|
+
grpc_combiner_scheduler(combiner_));
|
85
127
|
}
|
86
128
|
|
87
129
|
~GrpcPolledFdWindows() {
|
@@ -111,6 +153,33 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
111
153
|
grpc_slice_unref_internal(read_buf_);
|
112
154
|
GPR_ASSERT(!read_buf_has_data_);
|
113
155
|
read_buf_ = GRPC_SLICE_MALLOC(4192);
|
156
|
+
if (connect_done_) {
|
157
|
+
GRPC_CLOSURE_SCHED(&continue_register_for_on_readable_locked_,
|
158
|
+
GRPC_ERROR_NONE);
|
159
|
+
} else {
|
160
|
+
GPR_ASSERT(pending_continue_register_for_on_readable_locked_ == nullptr);
|
161
|
+
pending_continue_register_for_on_readable_locked_ =
|
162
|
+
&continue_register_for_on_readable_locked_;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
static void ContinueRegisterForOnReadableLocked(void* arg,
|
167
|
+
grpc_error* unused_error) {
|
168
|
+
GrpcPolledFdWindows* grpc_polled_fd =
|
169
|
+
static_cast<GrpcPolledFdWindows*>(arg);
|
170
|
+
grpc_polled_fd->InnerContinueRegisterForOnReadableLocked(GRPC_ERROR_NONE);
|
171
|
+
}
|
172
|
+
|
173
|
+
void InnerContinueRegisterForOnReadableLocked(grpc_error* unused_error) {
|
174
|
+
GRPC_CARES_TRACE_LOG(
|
175
|
+
"fd:|%s| InnerContinueRegisterForOnReadableLocked "
|
176
|
+
"wsa_connect_error_:%d",
|
177
|
+
GetName(), wsa_connect_error_);
|
178
|
+
GPR_ASSERT(connect_done_);
|
179
|
+
if (wsa_connect_error_ != 0) {
|
180
|
+
ScheduleAndNullReadClosure(GRPC_WSA_ERROR(wsa_connect_error_, "connect"));
|
181
|
+
return;
|
182
|
+
}
|
114
183
|
WSABUF buffer;
|
115
184
|
buffer.buf = (char*)GRPC_SLICE_START_PTR(read_buf_);
|
116
185
|
buffer.len = GRPC_SLICE_LENGTH(read_buf_);
|
@@ -123,13 +192,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
123
192
|
&winsocket_->read_info.overlapped, nullptr)) {
|
124
193
|
int wsa_last_error = WSAGetLastError();
|
125
194
|
char* msg = gpr_format_message(wsa_last_error);
|
126
|
-
grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
|
127
195
|
GRPC_CARES_TRACE_LOG(
|
128
|
-
"RegisterForOnReadableLocked
|
129
|
-
|
196
|
+
"fd:|%s| RegisterForOnReadableLocked WSARecvFrom error code:|%d| "
|
197
|
+
"msg:|%s|",
|
198
|
+
GetName(), wsa_last_error, msg);
|
130
199
|
gpr_free(msg);
|
131
200
|
if (wsa_last_error != WSA_IO_PENDING) {
|
132
|
-
ScheduleAndNullReadClosure(
|
201
|
+
ScheduleAndNullReadClosure(
|
202
|
+
GRPC_WSA_ERROR(wsa_last_error, "WSARecvFrom"));
|
133
203
|
return;
|
134
204
|
}
|
135
205
|
}
|
@@ -137,23 +207,68 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
137
207
|
}
|
138
208
|
|
139
209
|
void RegisterForOnWriteableLocked(grpc_closure* write_closure) override {
|
140
|
-
|
141
|
-
|
142
|
-
|
210
|
+
if (socket_type_ == SOCK_DGRAM) {
|
211
|
+
GRPC_CARES_TRACE_LOG("fd:|%s| RegisterForOnWriteableLocked called",
|
212
|
+
GetName());
|
213
|
+
} else {
|
214
|
+
GPR_ASSERT(socket_type_ == SOCK_STREAM);
|
215
|
+
GRPC_CARES_TRACE_LOG(
|
216
|
+
"fd:|%s| RegisterForOnWriteableLocked called tcp_write_state_: %d",
|
217
|
+
GetName(), tcp_write_state_);
|
218
|
+
}
|
143
219
|
GPR_ASSERT(write_closure_ == nullptr);
|
144
220
|
write_closure_ = write_closure;
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
221
|
+
if (connect_done_) {
|
222
|
+
GRPC_CLOSURE_SCHED(&continue_register_for_on_writeable_locked_,
|
223
|
+
GRPC_ERROR_NONE);
|
224
|
+
} else {
|
225
|
+
GPR_ASSERT(pending_continue_register_for_on_writeable_locked_ == nullptr);
|
226
|
+
pending_continue_register_for_on_writeable_locked_ =
|
227
|
+
&continue_register_for_on_writeable_locked_;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
static void ContinueRegisterForOnWriteableLocked(void* arg,
|
232
|
+
grpc_error* unused_error) {
|
233
|
+
GrpcPolledFdWindows* grpc_polled_fd =
|
234
|
+
static_cast<GrpcPolledFdWindows*>(arg);
|
235
|
+
grpc_polled_fd->InnerContinueRegisterForOnWriteableLocked(GRPC_ERROR_NONE);
|
236
|
+
}
|
237
|
+
|
238
|
+
void InnerContinueRegisterForOnWriteableLocked(grpc_error* unused_error) {
|
239
|
+
GRPC_CARES_TRACE_LOG(
|
240
|
+
"fd:|%s| InnerContinueRegisterForOnWriteableLocked "
|
241
|
+
"wsa_connect_error_:%d",
|
242
|
+
GetName(), wsa_connect_error_);
|
243
|
+
GPR_ASSERT(connect_done_);
|
244
|
+
if (wsa_connect_error_ != 0) {
|
245
|
+
ScheduleAndNullWriteClosure(
|
246
|
+
GRPC_WSA_ERROR(wsa_connect_error_, "connect"));
|
247
|
+
return;
|
248
|
+
}
|
249
|
+
if (socket_type_ == SOCK_DGRAM) {
|
250
|
+
ScheduleAndNullWriteClosure(GRPC_ERROR_NONE);
|
251
|
+
} else {
|
252
|
+
GPR_ASSERT(socket_type_ == SOCK_STREAM);
|
253
|
+
int wsa_error_code = 0;
|
254
|
+
switch (tcp_write_state_) {
|
255
|
+
case WRITE_IDLE:
|
256
|
+
ScheduleAndNullWriteClosure(GRPC_ERROR_NONE);
|
257
|
+
break;
|
258
|
+
case WRITE_REQUESTED:
|
259
|
+
tcp_write_state_ = WRITE_PENDING;
|
260
|
+
if (SendWriteBuf(nullptr, &winsocket_->write_info.overlapped,
|
261
|
+
&wsa_error_code) != 0) {
|
262
|
+
ScheduleAndNullWriteClosure(
|
263
|
+
GRPC_WSA_ERROR(wsa_error_code, "WSASend (overlapped)"));
|
264
|
+
} else {
|
265
|
+
grpc_socket_notify_on_write(winsocket_, &outer_write_closure_);
|
266
|
+
}
|
267
|
+
break;
|
268
|
+
case WRITE_PENDING:
|
269
|
+
case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY:
|
270
|
+
abort();
|
271
|
+
}
|
157
272
|
}
|
158
273
|
}
|
159
274
|
|
@@ -171,13 +286,15 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
171
286
|
|
172
287
|
const char* GetName() override { return name_; }
|
173
288
|
|
174
|
-
ares_ssize_t RecvFrom(
|
289
|
+
ares_ssize_t RecvFrom(WSAErrorContext* wsa_error_ctx, void* data,
|
290
|
+
ares_socket_t data_len, int flags,
|
175
291
|
struct sockaddr* from, ares_socklen_t* from_len) {
|
176
292
|
GRPC_CARES_TRACE_LOG(
|
177
|
-
"RecvFrom called
|
178
|
-
|
293
|
+
"fd:|%s| RecvFrom called read_buf_has_data:%d Current read buf "
|
294
|
+
"length:|%d|",
|
295
|
+
GetName(), read_buf_has_data_, GRPC_SLICE_LENGTH(read_buf_));
|
179
296
|
if (!read_buf_has_data_) {
|
180
|
-
|
297
|
+
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
|
181
298
|
return -1;
|
182
299
|
}
|
183
300
|
ares_ssize_t bytes_read = 0;
|
@@ -215,54 +332,99 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
215
332
|
return out;
|
216
333
|
}
|
217
334
|
|
218
|
-
int SendWriteBuf(LPDWORD bytes_sent_ptr, LPWSAOVERLAPPED overlapped
|
335
|
+
int SendWriteBuf(LPDWORD bytes_sent_ptr, LPWSAOVERLAPPED overlapped,
|
336
|
+
int* wsa_error_code) {
|
219
337
|
WSABUF buf;
|
220
338
|
buf.len = GRPC_SLICE_LENGTH(write_buf_);
|
221
339
|
buf.buf = (char*)GRPC_SLICE_START_PTR(write_buf_);
|
222
340
|
DWORD flags = 0;
|
223
341
|
int out = WSASend(grpc_winsocket_wrapped_socket(winsocket_), &buf, 1,
|
224
342
|
bytes_sent_ptr, flags, overlapped, nullptr);
|
343
|
+
*wsa_error_code = WSAGetLastError();
|
225
344
|
GRPC_CARES_TRACE_LOG(
|
226
|
-
"WSASend
|
227
|
-
"
|
228
|
-
|
345
|
+
"fd:|%s| SendWriteBuf WSASend buf.len:%d *bytes_sent_ptr:%d "
|
346
|
+
"overlapped:%p "
|
347
|
+
"return:%d *wsa_error_code:%d",
|
348
|
+
GetName(), buf.len, bytes_sent_ptr != nullptr ? *bytes_sent_ptr : 0,
|
349
|
+
overlapped, out, *wsa_error_code);
|
229
350
|
return out;
|
230
351
|
}
|
231
352
|
|
232
|
-
ares_ssize_t
|
233
|
-
|
353
|
+
ares_ssize_t SendV(WSAErrorContext* wsa_error_ctx, const struct iovec* iov,
|
354
|
+
int iov_count) {
|
355
|
+
GRPC_CARES_TRACE_LOG(
|
356
|
+
"fd:|%s| SendV called connect_done_:%d wsa_connect_error_:%d",
|
357
|
+
GetName(), connect_done_, wsa_connect_error_);
|
358
|
+
if (!connect_done_) {
|
359
|
+
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
|
360
|
+
return -1;
|
361
|
+
}
|
362
|
+
if (wsa_connect_error_ != 0) {
|
363
|
+
wsa_error_ctx->SetWSAError(wsa_connect_error_);
|
364
|
+
return -1;
|
365
|
+
}
|
366
|
+
switch (socket_type_) {
|
367
|
+
case SOCK_DGRAM:
|
368
|
+
return SendVUDP(wsa_error_ctx, iov, iov_count);
|
369
|
+
case SOCK_STREAM:
|
370
|
+
return SendVTCP(wsa_error_ctx, iov, iov_count);
|
371
|
+
default:
|
372
|
+
abort();
|
373
|
+
}
|
374
|
+
}
|
375
|
+
|
376
|
+
ares_ssize_t SendVUDP(WSAErrorContext* wsa_error_ctx, const struct iovec* iov,
|
377
|
+
int iov_count) {
|
378
|
+
// c-ares doesn't handle retryable errors on writes of UDP sockets.
|
379
|
+
// Therefore, the sendv handler for UDP sockets must only attempt
|
380
|
+
// to write everything inline.
|
381
|
+
GRPC_CARES_TRACE_LOG("fd:|%s| SendVUDP called", GetName());
|
382
|
+
GPR_ASSERT(GRPC_SLICE_LENGTH(write_buf_) == 0);
|
383
|
+
grpc_slice_unref_internal(write_buf_);
|
384
|
+
write_buf_ = FlattenIovec(iov, iov_count);
|
234
385
|
DWORD bytes_sent = 0;
|
235
|
-
|
236
|
-
|
237
|
-
|
386
|
+
int wsa_error_code = 0;
|
387
|
+
if (SendWriteBuf(&bytes_sent, nullptr, &wsa_error_code) != 0) {
|
388
|
+
wsa_error_ctx->SetWSAError(wsa_error_code);
|
389
|
+
char* msg = gpr_format_message(wsa_error_code);
|
238
390
|
GRPC_CARES_TRACE_LOG(
|
239
|
-
"
|
240
|
-
|
391
|
+
"fd:|%s| SendVUDP SendWriteBuf error code:%d msg:|%s|", GetName(),
|
392
|
+
wsa_error_code, msg);
|
241
393
|
gpr_free(msg);
|
242
|
-
|
243
|
-
WSASetLastError(WSAEWOULDBLOCK);
|
244
|
-
write_state_ = WRITE_REQUESTED;
|
245
|
-
}
|
394
|
+
return -1;
|
246
395
|
}
|
247
396
|
write_buf_ = grpc_slice_sub_no_ref(write_buf_, bytes_sent,
|
248
397
|
GRPC_SLICE_LENGTH(write_buf_));
|
249
398
|
return bytes_sent;
|
250
399
|
}
|
251
400
|
|
252
|
-
ares_ssize_t
|
253
|
-
|
254
|
-
|
255
|
-
|
401
|
+
ares_ssize_t SendVTCP(WSAErrorContext* wsa_error_ctx, const struct iovec* iov,
|
402
|
+
int iov_count) {
|
403
|
+
// The "sendv" handler on TCP sockets buffers up write
|
404
|
+
// requests and returns an artifical WSAEWOULDBLOCK. Writing that buffer out
|
405
|
+
// in the background, and making further send progress in general, will
|
406
|
+
// happen as long as c-ares continues to show interest in writeability on
|
407
|
+
// this fd.
|
408
|
+
GRPC_CARES_TRACE_LOG("fd:|%s| SendVTCP called tcp_write_state_:%d",
|
409
|
+
GetName(), tcp_write_state_);
|
410
|
+
switch (tcp_write_state_) {
|
256
411
|
case WRITE_IDLE:
|
412
|
+
tcp_write_state_ = WRITE_REQUESTED;
|
257
413
|
GPR_ASSERT(GRPC_SLICE_LENGTH(write_buf_) == 0);
|
258
414
|
grpc_slice_unref_internal(write_buf_);
|
259
415
|
write_buf_ = FlattenIovec(iov, iov_count);
|
260
|
-
|
416
|
+
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
|
417
|
+
return -1;
|
261
418
|
case WRITE_REQUESTED:
|
262
419
|
case WRITE_PENDING:
|
263
|
-
|
420
|
+
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
|
264
421
|
return -1;
|
265
422
|
case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY:
|
423
|
+
// c-ares is retrying a send on data that we previously returned
|
424
|
+
// WSAEWOULDBLOCK for, but then subsequently wrote out in the
|
425
|
+
// background. Right now, we assume that c-ares is retrying the same
|
426
|
+
// send again. If c-ares still needs to send even more data, we'll get
|
427
|
+
// to it eventually.
|
266
428
|
grpc_slice currently_attempted = FlattenIovec(iov, iov_count);
|
267
429
|
GPR_ASSERT(GRPC_SLICE_LENGTH(currently_attempted) >=
|
268
430
|
GRPC_SLICE_LENGTH(write_buf_));
|
@@ -272,31 +434,160 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
272
434
|
GRPC_SLICE_START_PTR(write_buf_)[i]);
|
273
435
|
total_sent++;
|
274
436
|
}
|
275
|
-
grpc_slice_unref_internal(
|
276
|
-
|
277
|
-
grpc_slice_sub_no_ref(currently_attempted, total_sent,
|
278
|
-
GRPC_SLICE_LENGTH(currently_attempted));
|
279
|
-
write_state_ = WRITE_IDLE;
|
280
|
-
total_sent += TrySendWriteBufSyncNonBlocking();
|
437
|
+
grpc_slice_unref_internal(currently_attempted);
|
438
|
+
tcp_write_state_ = WRITE_IDLE;
|
281
439
|
return total_sent;
|
282
440
|
}
|
283
441
|
abort();
|
284
442
|
}
|
285
443
|
|
286
|
-
|
444
|
+
static void OnTcpConnectLocked(void* arg, grpc_error* error) {
|
445
|
+
GrpcPolledFdWindows* grpc_polled_fd =
|
446
|
+
static_cast<GrpcPolledFdWindows*>(arg);
|
447
|
+
grpc_polled_fd->InnerOnTcpConnectLocked(error);
|
448
|
+
}
|
449
|
+
|
450
|
+
void InnerOnTcpConnectLocked(grpc_error* error) {
|
451
|
+
GRPC_CARES_TRACE_LOG(
|
452
|
+
"fd:%s InnerOnTcpConnectLocked error:|%s| "
|
453
|
+
"pending_register_for_readable:%" PRIdPTR
|
454
|
+
" pending_register_for_writeable:%" PRIdPTR,
|
455
|
+
GetName(), grpc_error_string(error),
|
456
|
+
pending_continue_register_for_on_readable_locked_,
|
457
|
+
pending_continue_register_for_on_writeable_locked_);
|
458
|
+
GPR_ASSERT(!connect_done_);
|
459
|
+
connect_done_ = true;
|
460
|
+
GPR_ASSERT(wsa_connect_error_ == 0);
|
461
|
+
if (error == GRPC_ERROR_NONE) {
|
462
|
+
DWORD transferred_bytes = 0;
|
463
|
+
DWORD flags;
|
464
|
+
BOOL wsa_success =
|
465
|
+
WSAGetOverlappedResult(grpc_winsocket_wrapped_socket(winsocket_),
|
466
|
+
&winsocket_->write_info.overlapped,
|
467
|
+
&transferred_bytes, FALSE, &flags);
|
468
|
+
GPR_ASSERT(transferred_bytes == 0);
|
469
|
+
if (!wsa_success) {
|
470
|
+
wsa_connect_error_ = WSAGetLastError();
|
471
|
+
char* msg = gpr_format_message(wsa_connect_error_);
|
472
|
+
GRPC_CARES_TRACE_LOG(
|
473
|
+
"fd:%s InnerOnTcpConnectLocked WSA overlapped result code:%d "
|
474
|
+
"msg:|%s|",
|
475
|
+
GetName(), wsa_connect_error_, msg);
|
476
|
+
gpr_free(msg);
|
477
|
+
}
|
478
|
+
} else {
|
479
|
+
// Spoof up an error code that will cause any future c-ares operations on
|
480
|
+
// this fd to abort.
|
481
|
+
wsa_connect_error_ = WSA_OPERATION_ABORTED;
|
482
|
+
}
|
483
|
+
if (pending_continue_register_for_on_readable_locked_ != nullptr) {
|
484
|
+
GRPC_CLOSURE_SCHED(pending_continue_register_for_on_readable_locked_,
|
485
|
+
GRPC_ERROR_NONE);
|
486
|
+
}
|
487
|
+
if (pending_continue_register_for_on_writeable_locked_ != nullptr) {
|
488
|
+
GRPC_CLOSURE_SCHED(pending_continue_register_for_on_writeable_locked_,
|
489
|
+
GRPC_ERROR_NONE);
|
490
|
+
}
|
491
|
+
}
|
492
|
+
|
493
|
+
int Connect(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target,
|
494
|
+
ares_socklen_t target_len) {
|
495
|
+
switch (socket_type_) {
|
496
|
+
case SOCK_DGRAM:
|
497
|
+
return ConnectUDP(wsa_error_ctx, target, target_len);
|
498
|
+
case SOCK_STREAM:
|
499
|
+
return ConnectTCP(wsa_error_ctx, target, target_len);
|
500
|
+
default:
|
501
|
+
abort();
|
502
|
+
}
|
503
|
+
}
|
504
|
+
|
505
|
+
int ConnectUDP(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target,
|
506
|
+
ares_socklen_t target_len) {
|
507
|
+
GRPC_CARES_TRACE_LOG("fd:%s ConnectUDP", GetName());
|
508
|
+
GPR_ASSERT(!connect_done_);
|
509
|
+
GPR_ASSERT(wsa_connect_error_ == 0);
|
287
510
|
SOCKET s = grpc_winsocket_wrapped_socket(winsocket_);
|
288
|
-
GRPC_CARES_TRACE_LOG("Connect: fd:|%s|", GetName());
|
289
511
|
int out =
|
290
512
|
WSAConnect(s, target, target_len, nullptr, nullptr, nullptr, nullptr);
|
291
|
-
|
513
|
+
wsa_connect_error_ = WSAGetLastError();
|
514
|
+
wsa_error_ctx->SetWSAError(wsa_connect_error_);
|
515
|
+
connect_done_ = true;
|
516
|
+
char* msg = gpr_format_message(wsa_connect_error_);
|
517
|
+
GRPC_CARES_TRACE_LOG("fd:%s WSAConnect error code:|%d| msg:|%s|", GetName(),
|
518
|
+
wsa_connect_error_, msg);
|
519
|
+
gpr_free(msg);
|
520
|
+
// c-ares expects a posix-style connect API
|
521
|
+
return out == 0 ? 0 : -1;
|
522
|
+
}
|
523
|
+
|
524
|
+
int ConnectTCP(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target,
|
525
|
+
ares_socklen_t target_len) {
|
526
|
+
GRPC_CARES_TRACE_LOG("fd:%s ConnectTCP", GetName());
|
527
|
+
LPFN_CONNECTEX ConnectEx;
|
528
|
+
GUID guid = WSAID_CONNECTEX;
|
529
|
+
DWORD ioctl_num_bytes;
|
530
|
+
SOCKET s = grpc_winsocket_wrapped_socket(winsocket_);
|
531
|
+
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
|
532
|
+
&ConnectEx, sizeof(ConnectEx), &ioctl_num_bytes, nullptr,
|
533
|
+
nullptr) != 0) {
|
534
|
+
int wsa_last_error = WSAGetLastError();
|
535
|
+
wsa_error_ctx->SetWSAError(wsa_last_error);
|
536
|
+
char* msg = gpr_format_message(wsa_last_error);
|
537
|
+
GRPC_CARES_TRACE_LOG(
|
538
|
+
"fd:%s WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER) error code:%d "
|
539
|
+
"msg:|%s|",
|
540
|
+
GetName(), wsa_last_error, msg);
|
541
|
+
gpr_free(msg);
|
542
|
+
connect_done_ = true;
|
543
|
+
wsa_connect_error_ = wsa_last_error;
|
544
|
+
return -1;
|
545
|
+
}
|
546
|
+
grpc_resolved_address wildcard4_addr;
|
547
|
+
grpc_resolved_address wildcard6_addr;
|
548
|
+
grpc_sockaddr_make_wildcards(0, &wildcard4_addr, &wildcard6_addr);
|
549
|
+
grpc_resolved_address* local_address = nullptr;
|
550
|
+
if (address_family_ == AF_INET) {
|
551
|
+
local_address = &wildcard4_addr;
|
552
|
+
} else {
|
553
|
+
local_address = &wildcard6_addr;
|
554
|
+
}
|
555
|
+
if (bind(s, (struct sockaddr*)local_address->addr,
|
556
|
+
(int)local_address->len) != 0) {
|
292
557
|
int wsa_last_error = WSAGetLastError();
|
558
|
+
wsa_error_ctx->SetWSAError(wsa_last_error);
|
293
559
|
char* msg = gpr_format_message(wsa_last_error);
|
294
|
-
GRPC_CARES_TRACE_LOG("
|
295
|
-
wsa_last_error, msg
|
560
|
+
GRPC_CARES_TRACE_LOG("fd:%s bind error code:%d msg:|%s|", GetName(),
|
561
|
+
wsa_last_error, msg);
|
296
562
|
gpr_free(msg);
|
297
|
-
|
563
|
+
connect_done_ = true;
|
564
|
+
wsa_connect_error_ = wsa_last_error;
|
565
|
+
return -1;
|
566
|
+
}
|
567
|
+
int out = 0;
|
568
|
+
if (ConnectEx(s, target, target_len, nullptr, 0, nullptr,
|
569
|
+
&winsocket_->write_info.overlapped) == 0) {
|
298
570
|
out = -1;
|
571
|
+
int wsa_last_error = WSAGetLastError();
|
572
|
+
wsa_error_ctx->SetWSAError(wsa_last_error);
|
573
|
+
char* msg = gpr_format_message(wsa_last_error);
|
574
|
+
GRPC_CARES_TRACE_LOG("fd:%s ConnectEx error code:%d msg:|%s|", GetName(),
|
575
|
+
wsa_last_error, msg);
|
576
|
+
gpr_free(msg);
|
577
|
+
if (wsa_last_error == WSA_IO_PENDING) {
|
578
|
+
// c-ares only understands WSAEINPROGRESS and EWOULDBLOCK error codes on
|
579
|
+
// connect, but an async connect on IOCP socket will give
|
580
|
+
// WSA_IO_PENDING, so we need to convert.
|
581
|
+
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
|
582
|
+
} else {
|
583
|
+
// By returning a non-retryable error to c-ares at this point,
|
584
|
+
// we're aborting the possibility of any future operations on this fd.
|
585
|
+
connect_done_ = true;
|
586
|
+
wsa_connect_error_ = wsa_last_error;
|
587
|
+
return -1;
|
588
|
+
}
|
299
589
|
}
|
590
|
+
grpc_socket_notify_on_write(winsocket_, &on_tcp_connect_locked_);
|
300
591
|
return out;
|
301
592
|
}
|
302
593
|
|
@@ -319,26 +610,27 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
319
610
|
* in subsequent c-ares reads. */
|
320
611
|
if (winsocket_->read_info.wsa_error != WSAEMSGSIZE) {
|
321
612
|
GRPC_ERROR_UNREF(error);
|
322
|
-
|
613
|
+
error = GRPC_WSA_ERROR(winsocket_->read_info.wsa_error,
|
614
|
+
"OnIocpReadableInner");
|
323
615
|
GRPC_CARES_TRACE_LOG(
|
324
|
-
"
|
325
|
-
|
326
|
-
|
327
|
-
|
616
|
+
"fd:|%s| OnIocpReadableInner winsocket_->read_info.wsa_error "
|
617
|
+
"code:|%d| msg:|%s|",
|
618
|
+
GetName(), winsocket_->read_info.wsa_error,
|
619
|
+
grpc_error_string(error));
|
328
620
|
}
|
329
621
|
}
|
330
622
|
}
|
331
623
|
if (error == GRPC_ERROR_NONE) {
|
332
|
-
read_buf_ = grpc_slice_sub_no_ref(
|
333
|
-
|
624
|
+
read_buf_ = grpc_slice_sub_no_ref(
|
625
|
+
read_buf_, 0, winsocket_->read_info.bytes_transferred);
|
334
626
|
read_buf_has_data_ = true;
|
335
627
|
} else {
|
336
628
|
grpc_slice_unref_internal(read_buf_);
|
337
629
|
read_buf_ = grpc_empty_slice();
|
338
630
|
}
|
339
631
|
GRPC_CARES_TRACE_LOG(
|
340
|
-
"OnIocpReadable finishing. read buf length now:|%d
|
341
|
-
GRPC_SLICE_LENGTH(read_buf_)
|
632
|
+
"fd:|%s| OnIocpReadable finishing. read buf length now:|%d|", GetName(),
|
633
|
+
GRPC_SLICE_LENGTH(read_buf_));
|
342
634
|
ScheduleAndNullReadClosure(error);
|
343
635
|
}
|
344
636
|
|
@@ -349,22 +641,26 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
349
641
|
|
350
642
|
void OnIocpWriteableInner(grpc_error* error) {
|
351
643
|
GRPC_CARES_TRACE_LOG("OnIocpWriteableInner. fd:|%s|", GetName());
|
644
|
+
GPR_ASSERT(socket_type_ == SOCK_STREAM);
|
352
645
|
if (error == GRPC_ERROR_NONE) {
|
353
646
|
if (winsocket_->write_info.wsa_error != 0) {
|
354
|
-
char* msg = gpr_format_message(winsocket_->write_info.wsa_error);
|
355
|
-
GRPC_CARES_TRACE_LOG(
|
356
|
-
"OnIocpWriteableInner. winsocket error:|%s|. fd:|%s|", msg,
|
357
|
-
GetName());
|
358
647
|
GRPC_ERROR_UNREF(error);
|
359
|
-
error =
|
360
|
-
|
648
|
+
error = GRPC_WSA_ERROR(winsocket_->write_info.wsa_error,
|
649
|
+
"OnIocpWriteableInner");
|
650
|
+
GRPC_CARES_TRACE_LOG(
|
651
|
+
"fd:|%s| OnIocpWriteableInner. winsocket_->write_info.wsa_error "
|
652
|
+
"code:|%d| msg:|%s|",
|
653
|
+
GetName(), winsocket_->write_info.wsa_error,
|
654
|
+
grpc_error_string(error));
|
361
655
|
}
|
362
656
|
}
|
363
|
-
GPR_ASSERT(
|
657
|
+
GPR_ASSERT(tcp_write_state_ == WRITE_PENDING);
|
364
658
|
if (error == GRPC_ERROR_NONE) {
|
365
|
-
|
659
|
+
tcp_write_state_ = WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY;
|
366
660
|
write_buf_ = grpc_slice_sub_no_ref(
|
367
|
-
write_buf_, 0, winsocket_->write_info.
|
661
|
+
write_buf_, 0, winsocket_->write_info.bytes_transferred);
|
662
|
+
GRPC_CARES_TRACE_LOG("fd:|%s| OnIocpWriteableInner. bytes transferred:%d",
|
663
|
+
GetName(), winsocket_->write_info.bytes_transferred);
|
368
664
|
} else {
|
369
665
|
grpc_slice_unref_internal(write_buf_);
|
370
666
|
write_buf_ = grpc_empty_slice();
|
@@ -386,9 +682,22 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
|
|
386
682
|
grpc_closure outer_read_closure_;
|
387
683
|
grpc_closure outer_write_closure_;
|
388
684
|
grpc_winsocket* winsocket_;
|
389
|
-
|
685
|
+
// tcp_write_state_ is only used on TCP GrpcPolledFds
|
686
|
+
WriteState tcp_write_state_;
|
390
687
|
char* name_ = nullptr;
|
391
688
|
bool gotten_into_driver_list_;
|
689
|
+
int address_family_;
|
690
|
+
int socket_type_;
|
691
|
+
grpc_closure on_tcp_connect_locked_;
|
692
|
+
bool connect_done_ = false;
|
693
|
+
int wsa_connect_error_ = 0;
|
694
|
+
// We don't run register_for_{readable,writeable} logic until
|
695
|
+
// a socket is connected. In the interim, we queue readable/writeable
|
696
|
+
// registrations with the following state.
|
697
|
+
grpc_closure continue_register_for_on_readable_locked_;
|
698
|
+
grpc_closure continue_register_for_on_writeable_locked_;
|
699
|
+
grpc_closure* pending_continue_register_for_on_readable_locked_ = nullptr;
|
700
|
+
grpc_closure* pending_continue_register_for_on_writeable_locked_ = nullptr;
|
392
701
|
};
|
393
702
|
|
394
703
|
struct SockToPolledFdEntry {
|
@@ -454,39 +763,53 @@ class SockToPolledFdMap {
|
|
454
763
|
* objects.
|
455
764
|
*/
|
456
765
|
static ares_socket_t Socket(int af, int type, int protocol, void* user_data) {
|
766
|
+
if (type != SOCK_DGRAM && type != SOCK_STREAM) {
|
767
|
+
GRPC_CARES_TRACE_LOG("Socket called with invalid socket type:%d", type);
|
768
|
+
return INVALID_SOCKET;
|
769
|
+
}
|
457
770
|
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
|
458
771
|
SOCKET s = WSASocket(af, type, protocol, nullptr, 0,
|
459
772
|
grpc_get_default_wsa_socket_flags());
|
460
773
|
if (s == INVALID_SOCKET) {
|
774
|
+
GRPC_CARES_TRACE_LOG(
|
775
|
+
"WSASocket failed with params af:%d type:%d protocol:%d", af, type,
|
776
|
+
protocol);
|
461
777
|
return s;
|
462
778
|
}
|
463
779
|
grpc_tcp_set_non_block(s);
|
464
780
|
GrpcPolledFdWindows* polled_fd =
|
465
|
-
New<GrpcPolledFdWindows>(s, map->combiner_);
|
781
|
+
New<GrpcPolledFdWindows>(s, map->combiner_, af, type);
|
782
|
+
GRPC_CARES_TRACE_LOG(
|
783
|
+
"fd:|%s| created with params af:%d type:%d protocol:%d",
|
784
|
+
polled_fd->GetName(), af, type, protocol);
|
466
785
|
map->AddNewSocket(s, polled_fd);
|
467
786
|
return s;
|
468
787
|
}
|
469
788
|
|
470
789
|
static int Connect(ares_socket_t as, const struct sockaddr* target,
|
471
790
|
ares_socklen_t target_len, void* user_data) {
|
791
|
+
WSAErrorContext wsa_error_ctx;
|
472
792
|
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
|
473
793
|
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as);
|
474
|
-
return polled_fd->Connect(target, target_len);
|
794
|
+
return polled_fd->Connect(&wsa_error_ctx, target, target_len);
|
475
795
|
}
|
476
796
|
|
477
797
|
static ares_ssize_t SendV(ares_socket_t as, const struct iovec* iov,
|
478
798
|
int iovec_count, void* user_data) {
|
799
|
+
WSAErrorContext wsa_error_ctx;
|
479
800
|
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
|
480
801
|
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as);
|
481
|
-
return polled_fd->SendV(iov, iovec_count);
|
802
|
+
return polled_fd->SendV(&wsa_error_ctx, iov, iovec_count);
|
482
803
|
}
|
483
804
|
|
484
805
|
static ares_ssize_t RecvFrom(ares_socket_t as, void* data, size_t data_len,
|
485
806
|
int flags, struct sockaddr* from,
|
486
807
|
ares_socklen_t* from_len, void* user_data) {
|
808
|
+
WSAErrorContext wsa_error_ctx;
|
487
809
|
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
|
488
810
|
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as);
|
489
|
-
return polled_fd->RecvFrom(data, data_len, flags, from,
|
811
|
+
return polled_fd->RecvFrom(&wsa_error_ctx, data, data_len, flags, from,
|
812
|
+
from_len);
|
490
813
|
}
|
491
814
|
|
492
815
|
static int CloseSocket(SOCKET s, void* user_data) {
|