grpc 1.18.0 → 1.19.0.pre1

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.

Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +301 -33
  3. data/include/grpc/grpc_security.h +195 -0
  4. data/include/grpc/impl/codegen/grpc_types.h +17 -1
  5. data/include/grpc/impl/codegen/port_platform.h +36 -0
  6. data/include/grpc/impl/codegen/slice.h +1 -1
  7. data/src/core/ext/filters/client_channel/channel_connectivity.cc +2 -0
  8. data/src/core/ext/filters/client_channel/client_channel.cc +74 -69
  9. data/src/core/ext/filters/client_channel/client_channel.h +2 -2
  10. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +5 -6
  11. data/src/core/ext/filters/client_channel/client_channel_channelz.h +5 -4
  12. data/src/core/ext/filters/client_channel/client_channel_factory.cc +2 -2
  13. data/src/core/ext/filters/client_channel/client_channel_factory.h +4 -4
  14. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +3 -3
  15. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +176 -0
  16. data/src/core/ext/filters/client_channel/global_subchannel_pool.h +68 -0
  17. data/src/core/ext/filters/client_channel/health/health_check_client.cc +10 -8
  18. data/src/core/ext/filters/client_channel/health/health_check_client.h +1 -1
  19. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +146 -156
  20. data/src/core/ext/filters/client_channel/lb_policy.cc +30 -1
  21. data/src/core/ext/filters/client_channel/lb_policy.h +29 -1
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +28 -30
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +5 -8
  24. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +5 -8
  25. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +23 -24
  26. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +80 -15
  27. data/src/core/ext/filters/client_channel/lb_policy_factory.h +6 -1
  28. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +2 -2
  29. data/src/core/ext/filters/client_channel/lb_policy_registry.h +1 -1
  30. data/src/core/ext/filters/client_channel/local_subchannel_pool.cc +96 -0
  31. data/src/core/ext/filters/client_channel/local_subchannel_pool.h +56 -0
  32. data/src/core/ext/filters/client_channel/parse_address.cc +24 -5
  33. data/src/core/ext/filters/client_channel/request_routing.cc +13 -3
  34. data/src/core/ext/filters/client_channel/request_routing.h +5 -1
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +11 -6
  36. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +2 -2
  37. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +7 -35
  38. data/src/core/ext/filters/client_channel/subchannel.cc +698 -791
  39. data/src/core/ext/filters/client_channel/subchannel.h +213 -123
  40. data/src/core/ext/filters/client_channel/subchannel_pool_interface.cc +97 -0
  41. data/src/core/ext/filters/client_channel/subchannel_pool_interface.h +94 -0
  42. data/src/core/ext/filters/http/client_authority_filter.cc +5 -2
  43. data/src/core/ext/filters/max_age/max_age_filter.cc +1 -1
  44. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +13 -12
  45. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +5 -7
  46. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +19 -27
  47. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +18 -19
  48. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +27 -6
  49. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -1
  50. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +3 -2
  51. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +1 -1
  52. data/src/core/ext/transport/chttp2/transport/writing.cc +8 -5
  53. data/src/core/lib/channel/handshaker.cc +141 -214
  54. data/src/core/lib/channel/handshaker.h +110 -101
  55. data/src/core/lib/channel/handshaker_factory.h +11 -19
  56. data/src/core/lib/channel/handshaker_registry.cc +64 -52
  57. data/src/core/lib/channel/handshaker_registry.h +21 -16
  58. data/src/core/lib/gpr/log_posix.cc +2 -1
  59. data/src/core/lib/gpr/time.cc +8 -0
  60. data/src/core/lib/gpr/time_posix.cc +8 -2
  61. data/src/core/lib/gprpp/optional.h +47 -0
  62. data/src/core/lib/http/httpcli_security_connector.cc +13 -14
  63. data/src/core/lib/iomgr/buffer_list.cc +182 -24
  64. data/src/core/lib/iomgr/buffer_list.h +70 -8
  65. data/src/core/lib/iomgr/combiner.cc +11 -3
  66. data/src/core/lib/iomgr/error.cc +9 -5
  67. data/src/core/lib/iomgr/ev_epoll1_linux.cc +3 -0
  68. data/src/core/lib/iomgr/ev_epollex_linux.cc +136 -162
  69. data/src/core/lib/iomgr/ev_poll_posix.cc +3 -0
  70. data/src/core/lib/iomgr/ev_posix.cc +4 -0
  71. data/src/core/lib/iomgr/ev_posix.h +4 -0
  72. data/src/core/lib/iomgr/exec_ctx.cc +1 -0
  73. data/src/core/lib/iomgr/exec_ctx.h +137 -8
  74. data/src/core/lib/iomgr/executor.cc +122 -87
  75. data/src/core/lib/iomgr/executor.h +53 -48
  76. data/src/core/lib/iomgr/fork_posix.cc +6 -4
  77. data/src/core/lib/iomgr/{network_status_tracker.cc → grpc_if_nametoindex.h} +8 -14
  78. data/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc +42 -0
  79. data/src/core/lib/iomgr/{network_status_tracker.h → grpc_if_nametoindex_unsupported.cc} +15 -9
  80. data/src/core/lib/iomgr/internal_errqueue.h +105 -3
  81. data/src/core/lib/iomgr/iomgr.cc +6 -5
  82. data/src/core/lib/iomgr/iomgr.h +8 -0
  83. data/src/core/lib/iomgr/iomgr_custom.cc +6 -2
  84. data/src/core/lib/iomgr/iomgr_internal.cc +4 -0
  85. data/src/core/lib/iomgr/iomgr_internal.h +4 -0
  86. data/src/core/lib/iomgr/iomgr_posix.cc +10 -1
  87. data/src/core/lib/iomgr/iomgr_windows.cc +8 -1
  88. data/src/core/lib/iomgr/port.h +1 -0
  89. data/src/core/lib/iomgr/resolve_address_posix.cc +4 -3
  90. data/src/core/lib/iomgr/resolve_address_windows.cc +2 -1
  91. data/src/core/lib/iomgr/tcp_custom.cc +0 -4
  92. data/src/core/lib/iomgr/tcp_posix.cc +58 -44
  93. data/src/core/lib/iomgr/tcp_uv.cc +0 -1
  94. data/src/core/lib/iomgr/tcp_windows.cc +0 -4
  95. data/src/core/lib/iomgr/timer_manager.cc +8 -0
  96. data/src/core/lib/iomgr/udp_server.cc +6 -4
  97. data/src/core/lib/json/json.cc +1 -4
  98. data/src/core/lib/security/credentials/alts/alts_credentials.cc +1 -1
  99. data/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc +2 -2
  100. data/src/core/lib/security/credentials/composite/composite_credentials.h +4 -0
  101. data/src/core/lib/security/credentials/credentials.h +9 -1
  102. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +15 -2
  103. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +2 -0
  104. data/src/core/lib/security/credentials/jwt/json_token.cc +1 -1
  105. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +1 -0
  106. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +3 -2
  107. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +2 -2
  108. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +1 -0
  109. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +192 -0
  110. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +213 -0
  111. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +10 -8
  112. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +6 -10
  113. data/src/core/lib/security/security_connector/local/local_security_connector.cc +10 -8
  114. data/src/core/lib/security/security_connector/security_connector.h +2 -2
  115. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +4 -6
  116. data/src/core/lib/security/security_connector/ssl_utils.h +33 -0
  117. data/src/core/lib/security/transport/security_handshaker.cc +267 -300
  118. data/src/core/lib/security/transport/security_handshaker.h +11 -2
  119. data/src/core/lib/security/transport/server_auth_filter.cc +1 -0
  120. data/src/core/lib/surface/call.cc +5 -1
  121. data/src/core/lib/surface/channel_init.h +5 -0
  122. data/src/core/lib/surface/completion_queue.cc +4 -7
  123. data/src/core/lib/surface/init.cc +5 -3
  124. data/src/core/lib/surface/init_secure.cc +1 -1
  125. data/src/core/lib/surface/server.cc +19 -17
  126. data/src/core/lib/surface/version.cc +1 -1
  127. data/src/core/lib/transport/service_config.h +1 -0
  128. data/src/core/lib/transport/static_metadata.cc +279 -279
  129. data/src/core/lib/transport/transport.cc +5 -3
  130. data/src/core/tsi/ssl_transport_security.cc +10 -4
  131. data/src/ruby/ext/grpc/extconf.rb +12 -4
  132. data/src/ruby/ext/grpc/rb_call_credentials.c +8 -5
  133. data/src/ruby/ext/grpc/rb_channel.c +14 -10
  134. data/src/ruby/ext/grpc/rb_channel_credentials.c +8 -4
  135. data/src/ruby/ext/grpc/rb_compression_options.c +9 -7
  136. data/src/ruby/ext/grpc/rb_event_thread.c +2 -0
  137. data/src/ruby/ext/grpc/rb_grpc.c +22 -23
  138. data/src/ruby/ext/grpc/rb_grpc.h +4 -2
  139. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +18 -0
  140. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +27 -0
  141. data/src/ruby/ext/grpc/rb_server.c +8 -4
  142. data/src/ruby/lib/grpc/version.rb +1 -1
  143. metadata +46 -39
  144. data/src/core/ext/filters/client_channel/subchannel_index.cc +0 -248
  145. data/src/core/ext/filters/client_channel/subchannel_index.h +0 -76
  146. data/src/core/lib/channel/handshaker_factory.cc +0 -42
@@ -24,6 +24,7 @@
24
24
  #include <grpc/support/log.h>
25
25
  #include <grpc/support/string_util.h>
26
26
  #include <grpc/support/time.h>
27
+ #include <inttypes.h>
27
28
  #include <pthread.h>
28
29
  #include <stdarg.h>
29
30
  #include <stdio.h>
@@ -83,7 +84,7 @@ void gpr_default_log(gpr_log_func_args* args) {
83
84
  }
84
85
 
85
86
  char* prefix;
86
- gpr_asprintf(&prefix, "%s%s.%09d %7tu %s:%d]",
87
+ gpr_asprintf(&prefix, "%s%s.%09d %7" PRIdPTR " %s:%d]",
87
88
  gpr_log_severity_string(args->severity), time_buffer,
88
89
  (int)(now.tv_nsec), gettid(), display_file, args->line);
89
90
 
@@ -135,6 +135,10 @@ gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {
135
135
  gpr_timespec sum;
136
136
  int64_t inc = 0;
137
137
  GPR_ASSERT(b.clock_type == GPR_TIMESPAN);
138
+ // tv_nsec in a timespan is always +ve. -ve timespan is represented as (-ve
139
+ // tv_sec, +ve tv_nsec). For example, timespan = -2.5 seconds is represented
140
+ // as {-3, 5e8, GPR_TIMESPAN}
141
+ GPR_ASSERT(b.tv_nsec >= 0);
138
142
  sum.clock_type = a.clock_type;
139
143
  sum.tv_nsec = a.tv_nsec + b.tv_nsec;
140
144
  if (sum.tv_nsec >= GPR_NS_PER_SEC) {
@@ -165,6 +169,10 @@ gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) {
165
169
  int64_t dec = 0;
166
170
  if (b.clock_type == GPR_TIMESPAN) {
167
171
  diff.clock_type = a.clock_type;
172
+ // tv_nsec in a timespan is always +ve. -ve timespan is represented as (-ve
173
+ // tv_sec, +ve tv_nsec). For example, timespan = -2.5 seconds is represented
174
+ // as {-3, 5e8, GPR_TIMESPAN}
175
+ GPR_ASSERT(b.tv_nsec >= 0);
168
176
  } else {
169
177
  GPR_ASSERT(a.clock_type == b.clock_type);
170
178
  diff.clock_type = GPR_TIMESPAN;
@@ -133,12 +133,18 @@ gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type) = now_impl;
133
133
  #ifdef GPR_LOW_LEVEL_COUNTERS
134
134
  gpr_atm gpr_now_call_count;
135
135
  #endif
136
-
137
136
  gpr_timespec gpr_now(gpr_clock_type clock_type) {
138
137
  #ifdef GPR_LOW_LEVEL_COUNTERS
139
138
  __atomic_fetch_add(&gpr_now_call_count, 1, __ATOMIC_RELAXED);
140
139
  #endif
141
- return gpr_now_impl(clock_type);
140
+ // validate clock type
141
+ GPR_ASSERT(clock_type == GPR_CLOCK_MONOTONIC ||
142
+ clock_type == GPR_CLOCK_REALTIME ||
143
+ clock_type == GPR_CLOCK_PRECISE);
144
+ gpr_timespec ts = gpr_now_impl(clock_type);
145
+ // tv_nsecs must be in the range [0, 1e9).
146
+ GPR_ASSERT(ts.tv_nsec >= 0 && ts.tv_nsec < 1e9);
147
+ return ts;
142
148
  }
143
149
 
144
150
  void gpr_sleep_until(gpr_timespec until) {
@@ -0,0 +1,47 @@
1
+ /*
2
+ *
3
+ * Copyright 2019 gRPC authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+
19
+ #ifndef GRPC_CORE_LIB_GPRPP_OPTIONAL_H
20
+ #define GRPC_CORE_LIB_GPRPP_OPTIONAL_H
21
+
22
+ namespace grpc_core {
23
+
24
+ /* A make-shift alternative for absl::Optional. This can be removed in favor of
25
+ * that once absl dependencies can be introduced. */
26
+ template <typename T>
27
+ class Optional {
28
+ public:
29
+ void set(const T& val) {
30
+ value_ = val;
31
+ set_ = true;
32
+ }
33
+
34
+ bool has_value() const { return set_; }
35
+
36
+ void reset() { set_ = false; }
37
+
38
+ T value() const { return value_; }
39
+
40
+ private:
41
+ T value_;
42
+ bool set_ = false;
43
+ };
44
+
45
+ } /* namespace grpc_core */
46
+
47
+ #endif /* GRPC_CORE_LIB_GPRPP_OPTIONAL_H */
@@ -67,7 +67,7 @@ class grpc_httpcli_ssl_channel_security_connector final
67
67
  }
68
68
 
69
69
  void add_handshakers(grpc_pollset_set* interested_parties,
70
- grpc_handshake_manager* handshake_mgr) override {
70
+ grpc_core::HandshakeManager* handshake_mgr) override {
71
71
  tsi_handshaker* handshaker = nullptr;
72
72
  if (handshaker_factory_ != nullptr) {
73
73
  tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
@@ -77,8 +77,7 @@ class grpc_httpcli_ssl_channel_security_connector final
77
77
  tsi_result_to_string(result));
78
78
  }
79
79
  }
80
- grpc_handshake_manager_add(
81
- handshake_mgr, grpc_security_handshaker_create(handshaker, this));
80
+ handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(handshaker, this));
82
81
  }
83
82
 
84
83
  tsi_ssl_client_handshaker_factory* handshaker_factory() const {
@@ -155,11 +154,11 @@ httpcli_ssl_channel_security_connector_create(
155
154
  typedef struct {
156
155
  void (*func)(void* arg, grpc_endpoint* endpoint);
157
156
  void* arg;
158
- grpc_handshake_manager* handshake_mgr;
157
+ grpc_core::RefCountedPtr<grpc_core::HandshakeManager> handshake_mgr;
159
158
  } on_done_closure;
160
159
 
161
160
  static void on_handshake_done(void* arg, grpc_error* error) {
162
- grpc_handshaker_args* args = static_cast<grpc_handshaker_args*>(arg);
161
+ auto* args = static_cast<grpc_core::HandshakerArgs*>(arg);
163
162
  on_done_closure* c = static_cast<on_done_closure*>(args->user_data);
164
163
  if (error != GRPC_ERROR_NONE) {
165
164
  const char* msg = grpc_error_string(error);
@@ -172,14 +171,13 @@ static void on_handshake_done(void* arg, grpc_error* error) {
172
171
  gpr_free(args->read_buffer);
173
172
  c->func(c->arg, args->endpoint);
174
173
  }
175
- grpc_handshake_manager_destroy(c->handshake_mgr);
176
- gpr_free(c);
174
+ grpc_core::Delete<on_done_closure>(c);
177
175
  }
178
176
 
179
177
  static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host,
180
178
  grpc_millis deadline,
181
179
  void (*on_done)(void* arg, grpc_endpoint* endpoint)) {
182
- on_done_closure* c = static_cast<on_done_closure*>(gpr_malloc(sizeof(*c)));
180
+ auto* c = grpc_core::New<on_done_closure>();
183
181
  const char* pem_root_certs =
184
182
  grpc_core::DefaultSslRootStore::GetPemRootCerts();
185
183
  const tsi_ssl_root_certs_store* root_store =
@@ -198,12 +196,13 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host,
198
196
  GPR_ASSERT(sc != nullptr);
199
197
  grpc_arg channel_arg = grpc_security_connector_to_arg(sc.get());
200
198
  grpc_channel_args args = {1, &channel_arg};
201
- c->handshake_mgr = grpc_handshake_manager_create();
202
- grpc_handshakers_add(HANDSHAKER_CLIENT, &args,
203
- nullptr /* interested_parties */, c->handshake_mgr);
204
- grpc_handshake_manager_do_handshake(
205
- c->handshake_mgr, tcp, nullptr /* channel_args */, deadline,
206
- nullptr /* acceptor */, on_handshake_done, c /* user_data */);
199
+ c->handshake_mgr = grpc_core::MakeRefCounted<grpc_core::HandshakeManager>();
200
+ grpc_core::HandshakerRegistry::AddHandshakers(
201
+ grpc_core::HANDSHAKER_CLIENT, &args, /*interested_parties=*/nullptr,
202
+ c->handshake_mgr.get());
203
+ c->handshake_mgr->DoHandshake(tcp, /*channel_args=*/nullptr, deadline,
204
+ /*acceptor=*/nullptr, on_handshake_done,
205
+ /*user_data=*/c);
207
206
  sc.reset(DEBUG_LOCATION, "httpcli");
208
207
  }
209
208
 
@@ -24,32 +24,13 @@
24
24
  #include <grpc/support/log.h>
25
25
 
26
26
  #ifdef GRPC_LINUX_ERRQUEUE
27
+ #include <netinet/in.h>
28
+ #include <string.h>
27
29
  #include <time.h>
28
30
 
29
31
  #include "src/core/lib/gprpp/memory.h"
30
32
 
31
33
  namespace grpc_core {
32
- void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no,
33
- void* arg) {
34
- GPR_DEBUG_ASSERT(head != nullptr);
35
- TracedBuffer* new_elem = New<TracedBuffer>(seq_no, arg);
36
- /* Store the current time as the sendmsg time. */
37
- new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME);
38
- new_elem->ts_.scheduled_time = gpr_inf_past(GPR_CLOCK_REALTIME);
39
- new_elem->ts_.sent_time = gpr_inf_past(GPR_CLOCK_REALTIME);
40
- new_elem->ts_.acked_time = gpr_inf_past(GPR_CLOCK_REALTIME);
41
- if (*head == nullptr) {
42
- *head = new_elem;
43
- return;
44
- }
45
- /* Append at the end. */
46
- TracedBuffer* ptr = *head;
47
- while (ptr->next_ != nullptr) {
48
- ptr = ptr->next_;
49
- }
50
- ptr->next_ = new_elem;
51
- }
52
-
53
34
  namespace {
54
35
  /** Fills gpr_timespec gts based on values from timespec ts */
55
36
  void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) {
@@ -68,10 +49,180 @@ void default_timestamps_callback(void* arg, grpc_core::Timestamps* ts,
68
49
  void (*timestamps_callback)(void*, grpc_core::Timestamps*,
69
50
  grpc_error* shutdown_err) =
70
51
  default_timestamps_callback;
52
+
53
+ /* Used to extract individual opt stats from cmsg, so as to avoid troubles with
54
+ * unaligned reads */
55
+ template <typename T>
56
+ T read_unaligned(const void* ptr) {
57
+ T val;
58
+ memcpy(&val, ptr, sizeof(val));
59
+ return val;
60
+ }
61
+
62
+ /* Extracts opt stats from the tcp_info struct \a info to \a metrics */
63
+ void extract_opt_stats_from_tcp_info(ConnectionMetrics* metrics,
64
+ const grpc_core::tcp_info* info) {
65
+ if (info == nullptr) {
66
+ return;
67
+ }
68
+ if (info->length > offsetof(grpc_core::tcp_info, tcpi_sndbuf_limited)) {
69
+ metrics->recurring_retrans.set(info->tcpi_retransmits);
70
+ metrics->is_delivery_rate_app_limited.set(
71
+ info->tcpi_delivery_rate_app_limited);
72
+ metrics->congestion_window.set(info->tcpi_snd_cwnd);
73
+ metrics->reordering.set(info->tcpi_reordering);
74
+ metrics->packet_retx.set(info->tcpi_total_retrans);
75
+ metrics->pacing_rate.set(info->tcpi_pacing_rate);
76
+ metrics->data_notsent.set(info->tcpi_notsent_bytes);
77
+ if (info->tcpi_min_rtt != UINT32_MAX) {
78
+ metrics->min_rtt.set(info->tcpi_min_rtt);
79
+ }
80
+ metrics->packet_sent.set(info->tcpi_data_segs_out);
81
+ metrics->delivery_rate.set(info->tcpi_delivery_rate);
82
+ metrics->busy_usec.set(info->tcpi_busy_time);
83
+ metrics->rwnd_limited_usec.set(info->tcpi_rwnd_limited);
84
+ metrics->sndbuf_limited_usec.set(info->tcpi_sndbuf_limited);
85
+ }
86
+ if (info->length > offsetof(grpc_core::tcp_info, tcpi_dsack_dups)) {
87
+ metrics->data_sent.set(info->tcpi_bytes_sent);
88
+ metrics->data_retx.set(info->tcpi_bytes_retrans);
89
+ metrics->packet_spurious_retx.set(info->tcpi_dsack_dups);
90
+ }
91
+ }
92
+
93
+ /** Extracts opt stats from the given control message \a opt_stats to the
94
+ * connection metrics \a metrics */
95
+ void extract_opt_stats_from_cmsg(ConnectionMetrics* metrics,
96
+ const cmsghdr* opt_stats) {
97
+ if (opt_stats == nullptr) {
98
+ return;
99
+ }
100
+ const auto* data = CMSG_DATA(opt_stats);
101
+ constexpr int64_t cmsg_hdr_len = CMSG_ALIGN(sizeof(struct cmsghdr));
102
+ const int64_t len = opt_stats->cmsg_len - cmsg_hdr_len;
103
+ int64_t offset = 0;
104
+
105
+ while (offset < len) {
106
+ const auto* attr = reinterpret_cast<const nlattr*>(data + offset);
107
+ const void* val = data + offset + NLA_HDRLEN;
108
+ switch (attr->nla_type) {
109
+ case TCP_NLA_BUSY: {
110
+ metrics->busy_usec.set(read_unaligned<uint64_t>(val));
111
+ break;
112
+ }
113
+ case TCP_NLA_RWND_LIMITED: {
114
+ metrics->rwnd_limited_usec.set(read_unaligned<uint64_t>(val));
115
+ break;
116
+ }
117
+ case TCP_NLA_SNDBUF_LIMITED: {
118
+ metrics->sndbuf_limited_usec.set(read_unaligned<uint64_t>(val));
119
+ break;
120
+ }
121
+ case TCP_NLA_PACING_RATE: {
122
+ metrics->pacing_rate.set(read_unaligned<uint64_t>(val));
123
+ break;
124
+ }
125
+ case TCP_NLA_DELIVERY_RATE: {
126
+ metrics->delivery_rate.set(read_unaligned<uint64_t>(val));
127
+ break;
128
+ }
129
+ case TCP_NLA_DELIVERY_RATE_APP_LMT: {
130
+ metrics->is_delivery_rate_app_limited.set(read_unaligned<uint8_t>(val));
131
+ break;
132
+ }
133
+ case TCP_NLA_SND_CWND: {
134
+ metrics->congestion_window.set(read_unaligned<uint32_t>(val));
135
+ break;
136
+ }
137
+ case TCP_NLA_MIN_RTT: {
138
+ metrics->min_rtt.set(read_unaligned<uint32_t>(val));
139
+ break;
140
+ }
141
+ case TCP_NLA_SRTT: {
142
+ metrics->srtt.set(read_unaligned<uint32_t>(val));
143
+ break;
144
+ }
145
+ case TCP_NLA_RECUR_RETRANS: {
146
+ metrics->recurring_retrans.set(read_unaligned<uint8_t>(val));
147
+ break;
148
+ }
149
+ case TCP_NLA_BYTES_SENT: {
150
+ metrics->data_sent.set(read_unaligned<uint64_t>(val));
151
+ break;
152
+ }
153
+ case TCP_NLA_DATA_SEGS_OUT: {
154
+ metrics->packet_sent.set(read_unaligned<uint64_t>(val));
155
+ break;
156
+ }
157
+ case TCP_NLA_TOTAL_RETRANS: {
158
+ metrics->packet_retx.set(read_unaligned<uint64_t>(val));
159
+ break;
160
+ }
161
+ case TCP_NLA_DELIVERED: {
162
+ metrics->packet_delivered.set(read_unaligned<uint32_t>(val));
163
+ break;
164
+ }
165
+ case TCP_NLA_DELIVERED_CE: {
166
+ metrics->packet_delivered_ce.set(read_unaligned<uint32_t>(val));
167
+ break;
168
+ }
169
+ case TCP_NLA_BYTES_RETRANS: {
170
+ metrics->data_retx.set(read_unaligned<uint64_t>(val));
171
+ break;
172
+ }
173
+ case TCP_NLA_DSACK_DUPS: {
174
+ metrics->packet_spurious_retx.set(read_unaligned<uint32_t>(val));
175
+ break;
176
+ }
177
+ case TCP_NLA_REORDERING: {
178
+ metrics->reordering.set(read_unaligned<uint32_t>(val));
179
+ break;
180
+ }
181
+ case TCP_NLA_SND_SSTHRESH: {
182
+ metrics->snd_ssthresh.set(read_unaligned<uint32_t>(val));
183
+ break;
184
+ }
185
+ }
186
+ offset += NLA_ALIGN(attr->nla_len);
187
+ }
188
+ }
189
+
190
+ static int get_socket_tcp_info(grpc_core::tcp_info* info, int fd) {
191
+ memset(info, 0, sizeof(*info));
192
+ info->length = sizeof(*info) - sizeof(socklen_t);
193
+ return getsockopt(fd, IPPROTO_TCP, TCP_INFO, info, &(info->length));
194
+ }
71
195
  } /* namespace */
72
196
 
197
+ void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, int fd,
198
+ void* arg) {
199
+ GPR_DEBUG_ASSERT(head != nullptr);
200
+ TracedBuffer* new_elem = New<TracedBuffer>(seq_no, arg);
201
+ /* Store the current time as the sendmsg time. */
202
+ new_elem->ts_.sendmsg_time.time = gpr_now(GPR_CLOCK_REALTIME);
203
+ new_elem->ts_.scheduled_time.time = gpr_inf_past(GPR_CLOCK_REALTIME);
204
+ new_elem->ts_.sent_time.time = gpr_inf_past(GPR_CLOCK_REALTIME);
205
+ new_elem->ts_.acked_time.time = gpr_inf_past(GPR_CLOCK_REALTIME);
206
+
207
+ if (get_socket_tcp_info(&new_elem->ts_.info, fd) == 0) {
208
+ extract_opt_stats_from_tcp_info(&new_elem->ts_.sendmsg_time.metrics,
209
+ &new_elem->ts_.info);
210
+ }
211
+ if (*head == nullptr) {
212
+ *head = new_elem;
213
+ return;
214
+ }
215
+ /* Append at the end. */
216
+ TracedBuffer* ptr = *head;
217
+ while (ptr->next_ != nullptr) {
218
+ ptr = ptr->next_;
219
+ }
220
+ ptr->next_ = new_elem;
221
+ }
222
+
73
223
  void TracedBuffer::ProcessTimestamp(TracedBuffer** head,
74
224
  struct sock_extended_err* serr,
225
+ struct cmsghdr* opt_stats,
75
226
  struct scm_timestamping* tss) {
76
227
  GPR_DEBUG_ASSERT(head != nullptr);
77
228
  TracedBuffer* elem = *head;
@@ -82,15 +233,22 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head,
82
233
  if (serr->ee_data >= elem->seq_no_) {
83
234
  switch (serr->ee_info) {
84
235
  case SCM_TSTAMP_SCHED:
85
- fill_gpr_from_timestamp(&(elem->ts_.scheduled_time), &(tss->ts[0]));
236
+ fill_gpr_from_timestamp(&(elem->ts_.scheduled_time.time),
237
+ &(tss->ts[0]));
238
+ extract_opt_stats_from_cmsg(&(elem->ts_.scheduled_time.metrics),
239
+ opt_stats);
86
240
  elem = elem->next_;
87
241
  break;
88
242
  case SCM_TSTAMP_SND:
89
- fill_gpr_from_timestamp(&(elem->ts_.sent_time), &(tss->ts[0]));
243
+ fill_gpr_from_timestamp(&(elem->ts_.sent_time.time), &(tss->ts[0]));
244
+ extract_opt_stats_from_cmsg(&(elem->ts_.sent_time.metrics),
245
+ opt_stats);
90
246
  elem = elem->next_;
91
247
  break;
92
248
  case SCM_TSTAMP_ACK:
93
- fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0]));
249
+ fill_gpr_from_timestamp(&(elem->ts_.acked_time.time), &(tss->ts[0]));
250
+ extract_opt_stats_from_cmsg(&(elem->ts_.acked_time.metrics),
251
+ opt_stats);
94
252
  /* Got all timestamps. Do the callback and free this TracedBuffer.
95
253
  * The thing below can be passed by value if we don't want the
96
254
  * restriction on the lifetime. */
@@ -26,19 +26,78 @@
26
26
  #include <grpc/support/time.h>
27
27
 
28
28
  #include "src/core/lib/gprpp/memory.h"
29
+ #include "src/core/lib/gprpp/optional.h"
29
30
  #include "src/core/lib/iomgr/error.h"
30
31
  #include "src/core/lib/iomgr/internal_errqueue.h"
31
32
 
32
33
  namespace grpc_core {
34
+
35
+ struct ConnectionMetrics {
36
+ /* Delivery rate in Bytes/s. */
37
+ Optional<uint64_t> delivery_rate;
38
+ /* If the delivery rate is limited by the application, this is set to true. */
39
+ Optional<bool> is_delivery_rate_app_limited;
40
+ /* Total packets retransmitted. */
41
+ Optional<uint32_t> packet_retx;
42
+ /* Total packets retransmitted spuriously. This metric is smaller than or
43
+ equal to packet_retx. */
44
+ Optional<uint32_t> packet_spurious_retx;
45
+ /* Total packets sent. */
46
+ Optional<uint32_t> packet_sent;
47
+ /* Total packets delivered. */
48
+ Optional<uint32_t> packet_delivered;
49
+ /* Total packets delivered with ECE marked. This metric is smaller than or
50
+ equal to packet_delivered. */
51
+ Optional<uint32_t> packet_delivered_ce;
52
+ /* Total bytes lost so far. */
53
+ Optional<uint64_t> data_retx;
54
+ /* Total bytes sent so far. */
55
+ Optional<uint64_t> data_sent;
56
+ /* Total bytes in write queue but not sent. */
57
+ Optional<uint64_t> data_notsent;
58
+ /* Pacing rate of the connection in Bps */
59
+ Optional<uint64_t> pacing_rate;
60
+ /* Minimum RTT observed in usec. */
61
+ Optional<uint32_t> min_rtt;
62
+ /* Smoothed RTT in usec */
63
+ Optional<uint32_t> srtt;
64
+ /* Send congestion window. */
65
+ Optional<uint32_t> congestion_window;
66
+ /* Slow start threshold in packets. */
67
+ Optional<uint32_t> snd_ssthresh;
68
+ /* Maximum degree of reordering (i.e., maximum number of packets reodered)
69
+ on the connection. */
70
+ Optional<uint32_t> reordering;
71
+ /* Represents the number of recurring retransmissions of the first sequence
72
+ that is not acknowledged yet. */
73
+ Optional<uint8_t> recurring_retrans;
74
+ /* The cumulative time (in usec) that the transport protocol was busy
75
+ sending data. */
76
+ Optional<uint64_t> busy_usec;
77
+ /* The cumulative time (in usec) that the transport protocol was limited by
78
+ the receive window size. */
79
+ Optional<uint64_t> rwnd_limited_usec;
80
+ /* The cumulative time (in usec) that the transport protocol was limited by
81
+ the send buffer size. */
82
+ Optional<uint64_t> sndbuf_limited_usec;
83
+ };
84
+
85
+ struct Timestamp {
86
+ gpr_timespec time;
87
+ ConnectionMetrics metrics; /* Metrics collected with this timestamp */
88
+ };
89
+
33
90
  struct Timestamps {
34
- /* TODO(yashykt): This would also need to store OPTSTAT once support is added
35
- */
36
- gpr_timespec sendmsg_time;
37
- gpr_timespec scheduled_time;
38
- gpr_timespec sent_time;
39
- gpr_timespec acked_time;
91
+ Timestamp sendmsg_time;
92
+ Timestamp scheduled_time;
93
+ Timestamp sent_time;
94
+ Timestamp acked_time;
40
95
 
41
96
  uint32_t byte_offset; /* byte offset relative to the start of the RPC */
97
+
98
+ #ifdef GRPC_LINUX_ERRQUEUE
99
+ grpc_core::tcp_info info; /* tcp_info collected on sendmsg */
100
+ #endif /* GRPC_LINUX_ERRQUEUE */
42
101
  };
43
102
 
44
103
  /** TracedBuffer is a class to keep track of timestamps for a specific buffer in
@@ -58,13 +117,14 @@ class TracedBuffer {
58
117
  /** Add a new entry in the TracedBuffer list pointed to by head. Also saves
59
118
  * sendmsg_time with the current timestamp. */
60
119
  static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no,
61
- void* arg);
120
+ int fd, void* arg);
62
121
 
63
122
  /** Processes a received timestamp based on sock_extended_err and
64
123
  * scm_timestamping structures. It will invoke the timestamps callback if the
65
124
  * timestamp type is SCM_TSTAMP_ACK. */
66
125
  static void ProcessTimestamp(grpc_core::TracedBuffer** head,
67
126
  struct sock_extended_err* serr,
127
+ struct cmsghdr* opt_stats,
68
128
  struct scm_timestamping* tss);
69
129
 
70
130
  /** Cleans the list by calling the callback for each traced buffer in the list
@@ -88,7 +148,9 @@ class TracedBuffer {
88
148
  public:
89
149
  /* Dummy shutdown function */
90
150
  static void Shutdown(grpc_core::TracedBuffer** head, void* remaining,
91
- grpc_error* shutdown_err) {}
151
+ grpc_error* shutdown_err) {
152
+ GRPC_ERROR_UNREF(shutdown_err);
153
+ }
92
154
  };
93
155
  #endif /* GRPC_LINUX_ERRQUEUE */
94
156