bad_ping.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. *
  3. * Copyright 2017 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. #include <string.h>
  19. #include <grpc/support/alloc.h>
  20. #include <grpc/support/log.h>
  21. #include <grpc/support/sync.h>
  22. #include <grpc/support/time.h>
  23. #include "src/core/lib/channel/channel_args.h"
  24. #include "src/core/lib/gpr/useful.h"
  25. #include "src/core/lib/surface/channel.h"
  26. #include "test/core/end2end/cq_verifier.h"
  27. #include "test/core/end2end/end2end_tests.h"
  28. #define MAX_PING_STRIKES 2
  29. static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
  30. static void drain_cq(grpc_completion_queue* cq) {
  31. grpc_event ev;
  32. do {
  33. ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
  34. nullptr);
  35. } while (ev.type != GRPC_QUEUE_SHUTDOWN);
  36. }
  37. static void shutdown_server(grpc_end2end_test_fixture* f) {
  38. if (!f->server) return;
  39. grpc_server_destroy(f->server);
  40. f->server = nullptr;
  41. }
  42. static void shutdown_client(grpc_end2end_test_fixture* f) {
  43. if (!f->client) return;
  44. grpc_channel_destroy(f->client);
  45. f->client = nullptr;
  46. }
  47. static void end_test(grpc_end2end_test_fixture* f) {
  48. shutdown_server(f);
  49. shutdown_client(f);
  50. grpc_completion_queue_shutdown(f->cq);
  51. drain_cq(f->cq);
  52. grpc_completion_queue_destroy(f->cq);
  53. grpc_completion_queue_destroy(f->shutdown_cq);
  54. }
  55. // Send more pings than server allows to trigger server's GOAWAY.
  56. static void test_bad_ping(grpc_end2end_test_config config) {
  57. grpc_end2end_test_fixture f = config.create_fixture(nullptr, nullptr);
  58. cq_verifier* cqv = cq_verifier_create(f.cq);
  59. grpc_arg client_a[] = {
  60. grpc_channel_arg_integer_create(
  61. const_cast<char*>(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA), 0),
  62. grpc_channel_arg_integer_create(
  63. const_cast<char*>(GRPC_ARG_HTTP2_BDP_PROBE), 0)};
  64. grpc_arg server_a[] = {
  65. grpc_channel_arg_integer_create(
  66. const_cast<char*>(
  67. GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS),
  68. 300000 /* 5 minutes */),
  69. grpc_channel_arg_integer_create(
  70. const_cast<char*>(GRPC_ARG_HTTP2_MAX_PING_STRIKES), MAX_PING_STRIKES),
  71. grpc_channel_arg_integer_create(
  72. const_cast<char*>(GRPC_ARG_HTTP2_BDP_PROBE), 0)};
  73. grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
  74. grpc_channel_args server_args = {GPR_ARRAY_SIZE(server_a), server_a};
  75. config.init_client(&f, &client_args);
  76. config.init_server(&f, &server_args);
  77. grpc_call* c;
  78. grpc_call* s;
  79. gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
  80. grpc_op ops[6];
  81. grpc_op* op;
  82. grpc_metadata_array initial_metadata_recv;
  83. grpc_metadata_array trailing_metadata_recv;
  84. grpc_metadata_array request_metadata_recv;
  85. grpc_call_details call_details;
  86. grpc_status_code status;
  87. grpc_call_error error;
  88. grpc_slice details;
  89. int was_cancelled = 2;
  90. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  91. grpc_slice_from_static_string("/foo"), nullptr,
  92. deadline, nullptr);
  93. GPR_ASSERT(c);
  94. grpc_metadata_array_init(&initial_metadata_recv);
  95. grpc_metadata_array_init(&trailing_metadata_recv);
  96. grpc_metadata_array_init(&request_metadata_recv);
  97. grpc_call_details_init(&call_details);
  98. memset(ops, 0, sizeof(ops));
  99. op = ops;
  100. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  101. op->data.send_initial_metadata.count = 0;
  102. op->data.send_initial_metadata.metadata = nullptr;
  103. op->flags = 0;
  104. op->reserved = nullptr;
  105. op++;
  106. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  107. op->flags = 0;
  108. op->reserved = nullptr;
  109. op++;
  110. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  111. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  112. op->flags = 0;
  113. op->reserved = nullptr;
  114. op++;
  115. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  116. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  117. op->data.recv_status_on_client.status = &status;
  118. op->data.recv_status_on_client.status_details = &details;
  119. op->flags = 0;
  120. op->reserved = nullptr;
  121. op++;
  122. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  123. nullptr);
  124. GPR_ASSERT(GRPC_CALL_OK == error);
  125. error =
  126. grpc_server_request_call(f.server, &s, &call_details,
  127. &request_metadata_recv, f.cq, f.cq, tag(101));
  128. GPR_ASSERT(GRPC_CALL_OK == error);
  129. CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  130. cq_verify(cqv);
  131. // Send too many pings to the server to trigger the punishment:
  132. // The first ping will let server mark its last_recv time. Afterwards, each
  133. // ping will trigger a ping strike, and we need at least MAX_PING_STRIKES
  134. // strikes to trigger the punishment. So (MAX_PING_STRIKES + 2) pings are
  135. // needed here.
  136. int i;
  137. for (i = 1; i <= MAX_PING_STRIKES + 2; i++) {
  138. grpc_channel_ping(f.client, f.cq, tag(200 + i), nullptr);
  139. CQ_EXPECT_COMPLETION(cqv, tag(200 + i), 1);
  140. if (i == MAX_PING_STRIKES + 2) {
  141. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  142. }
  143. cq_verify(cqv);
  144. }
  145. memset(ops, 0, sizeof(ops));
  146. op = ops;
  147. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  148. op->data.send_initial_metadata.count = 0;
  149. op->flags = 0;
  150. op->reserved = nullptr;
  151. op++;
  152. op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  153. op->data.send_status_from_server.trailing_metadata_count = 0;
  154. op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
  155. grpc_slice status_details = grpc_slice_from_static_string("xyz");
  156. op->data.send_status_from_server.status_details = &status_details;
  157. op->flags = 0;
  158. op->reserved = nullptr;
  159. op++;
  160. op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  161. op->data.recv_close_on_server.cancelled = &was_cancelled;
  162. op->flags = 0;
  163. op->reserved = nullptr;
  164. op++;
  165. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
  166. nullptr);
  167. GPR_ASSERT(GRPC_CALL_OK == error);
  168. CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  169. cq_verify(cqv);
  170. grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
  171. CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1);
  172. cq_verify(cqv);
  173. grpc_call_unref(s);
  174. // The connection should be closed immediately after the misbehaved pings,
  175. // the in-progress RPC should fail.
  176. GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
  177. GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
  178. GPR_ASSERT(was_cancelled == 1);
  179. grpc_slice_unref(details);
  180. grpc_metadata_array_destroy(&initial_metadata_recv);
  181. grpc_metadata_array_destroy(&trailing_metadata_recv);
  182. grpc_metadata_array_destroy(&request_metadata_recv);
  183. grpc_call_details_destroy(&call_details);
  184. grpc_call_unref(c);
  185. cq_verifier_destroy(cqv);
  186. end_test(&f);
  187. config.tear_down_data(&f);
  188. }
  189. // Try sending more pings than server allows, but server should be fine because
  190. // max_pings_without_data should limit pings sent out on wire.
  191. static void test_pings_without_data(grpc_end2end_test_config config) {
  192. grpc_end2end_test_fixture f = config.create_fixture(nullptr, nullptr);
  193. cq_verifier* cqv = cq_verifier_create(f.cq);
  194. // Only allow MAX_PING_STRIKES pings without data (DATA/HEADERS/WINDOW_UPDATE)
  195. // so that the transport will throttle the excess pings.
  196. grpc_arg client_a[] = {
  197. grpc_channel_arg_integer_create(
  198. const_cast<char*>(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA),
  199. MAX_PING_STRIKES),
  200. grpc_channel_arg_integer_create(
  201. const_cast<char*>(GRPC_ARG_HTTP2_BDP_PROBE), 0)};
  202. grpc_arg server_a[] = {
  203. grpc_channel_arg_integer_create(
  204. const_cast<char*>(
  205. GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS),
  206. 300000 /* 5 minutes */),
  207. grpc_channel_arg_integer_create(
  208. const_cast<char*>(GRPC_ARG_HTTP2_MAX_PING_STRIKES), MAX_PING_STRIKES),
  209. grpc_channel_arg_integer_create(
  210. const_cast<char*>(GRPC_ARG_HTTP2_BDP_PROBE), 0)};
  211. grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
  212. grpc_channel_args server_args = {GPR_ARRAY_SIZE(server_a), server_a};
  213. config.init_client(&f, &client_args);
  214. config.init_server(&f, &server_args);
  215. grpc_call* c;
  216. grpc_call* s;
  217. gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
  218. grpc_op ops[6];
  219. grpc_op* op;
  220. grpc_metadata_array initial_metadata_recv;
  221. grpc_metadata_array trailing_metadata_recv;
  222. grpc_metadata_array request_metadata_recv;
  223. grpc_call_details call_details;
  224. grpc_status_code status;
  225. grpc_call_error error;
  226. grpc_slice details;
  227. int was_cancelled = 2;
  228. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  229. grpc_slice_from_static_string("/foo"), nullptr,
  230. deadline, nullptr);
  231. GPR_ASSERT(c);
  232. grpc_metadata_array_init(&initial_metadata_recv);
  233. grpc_metadata_array_init(&trailing_metadata_recv);
  234. grpc_metadata_array_init(&request_metadata_recv);
  235. grpc_call_details_init(&call_details);
  236. memset(ops, 0, sizeof(ops));
  237. op = ops;
  238. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  239. op->data.send_initial_metadata.count = 0;
  240. op->data.send_initial_metadata.metadata = nullptr;
  241. op->flags = 0;
  242. op->reserved = nullptr;
  243. op++;
  244. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  245. op->flags = 0;
  246. op->reserved = nullptr;
  247. op++;
  248. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  249. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  250. op->flags = 0;
  251. op->reserved = nullptr;
  252. op++;
  253. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  254. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  255. op->data.recv_status_on_client.status = &status;
  256. op->data.recv_status_on_client.status_details = &details;
  257. op->flags = 0;
  258. op->reserved = nullptr;
  259. op++;
  260. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  261. nullptr);
  262. GPR_ASSERT(GRPC_CALL_OK == error);
  263. error =
  264. grpc_server_request_call(f.server, &s, &call_details,
  265. &request_metadata_recv, f.cq, f.cq, tag(101));
  266. GPR_ASSERT(GRPC_CALL_OK == error);
  267. CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  268. cq_verify(cqv);
  269. // Send too many pings to the server similar to the previous test case.
  270. // However, since we set the MAX_PINGS_WITHOUT_DATA at the client side, only
  271. // MAX_PING_STRIKES will actually be sent and the rpc will still succeed.
  272. int i;
  273. for (i = 1; i <= MAX_PING_STRIKES + 2; i++) {
  274. grpc_channel_ping(f.client, f.cq, tag(200 + i), nullptr);
  275. if (i <= MAX_PING_STRIKES) {
  276. CQ_EXPECT_COMPLETION(cqv, tag(200 + i), 1);
  277. }
  278. cq_verify(cqv);
  279. }
  280. memset(ops, 0, sizeof(ops));
  281. op = ops;
  282. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  283. op->data.send_initial_metadata.count = 0;
  284. op->flags = 0;
  285. op->reserved = nullptr;
  286. op++;
  287. op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  288. op->data.send_status_from_server.trailing_metadata_count = 0;
  289. op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
  290. grpc_slice status_details = grpc_slice_from_static_string("xyz");
  291. op->data.send_status_from_server.status_details = &status_details;
  292. op->flags = 0;
  293. op->reserved = nullptr;
  294. op++;
  295. op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  296. op->data.recv_close_on_server.cancelled = &was_cancelled;
  297. op->flags = 0;
  298. op->reserved = nullptr;
  299. op++;
  300. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
  301. nullptr);
  302. GPR_ASSERT(GRPC_CALL_OK == error);
  303. CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  304. // Client call should return.
  305. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  306. cq_verify(cqv);
  307. grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
  308. CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1);
  309. // Also expect the previously blocked pings to complete with an error
  310. CQ_EXPECT_COMPLETION(cqv, tag(200 + MAX_PING_STRIKES + 1), 0);
  311. CQ_EXPECT_COMPLETION(cqv, tag(200 + MAX_PING_STRIKES + 2), 0);
  312. cq_verify(cqv);
  313. grpc_call_unref(s);
  314. // The rpc should be successful.
  315. GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
  316. GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
  317. grpc_slice_unref(details);
  318. grpc_metadata_array_destroy(&initial_metadata_recv);
  319. grpc_metadata_array_destroy(&trailing_metadata_recv);
  320. grpc_metadata_array_destroy(&request_metadata_recv);
  321. grpc_call_details_destroy(&call_details);
  322. grpc_call_unref(c);
  323. cq_verifier_destroy(cqv);
  324. end_test(&f);
  325. config.tear_down_data(&f);
  326. }
  327. void bad_ping(grpc_end2end_test_config config) {
  328. GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
  329. test_bad_ping(config);
  330. test_pings_without_data(config);
  331. }
  332. void bad_ping_pre_init(void) {}