static void send_handshake_bytes_to_peer(grpc_exec_ctx *exec_ctx, grpc_security_handshake *h) { size_t offset = 0; tsi_result result = TSI_OK; gpr_slice to_send; do { size_t to_send_size = h->handshake_buffer_size - offset; result = tsi_handshaker_get_bytes_to_send_to_peer( h->handshaker, h->handshake_buffer + offset, &to_send_size); offset += to_send_size; if (result == TSI_INCOMPLETE_DATA) { h->handshake_buffer_size *= 2; h->handshake_buffer = gpr_realloc(h->handshake_buffer, h->handshake_buffer_size); } } while (result == TSI_INCOMPLETE_DATA); if (result != TSI_OK) { security_handshake_done(exec_ctx, h, grpc_set_tsi_error_result( GRPC_ERROR_CREATE("Handshake failed"), result)); return; } to_send = gpr_slice_from_copied_buffer((const char *)h->handshake_buffer, offset); gpr_slice_buffer_reset_and_unref(&h->outgoing); gpr_slice_buffer_add(&h->outgoing, to_send); /* TODO(klempner,jboeuf): This should probably use the client setup deadline */ grpc_endpoint_write(exec_ctx, h->wrapped_endpoint, &h->outgoing, &h->on_handshake_data_sent_to_peer); }
static void handle_write(grpc_exec_ctx *exec_ctx) { gpr_slice slice = gpr_slice_from_copied_buffer(state.response_payload, state.response_payload_length); gpr_slice_buffer_reset_and_unref(&state.outgoing_buffer); gpr_slice_buffer_add(&state.outgoing_buffer, slice); grpc_endpoint_write(exec_ctx, state.tcp, &state.outgoing_buffer, &on_write); }
static void test_dump_slice(void) { static const char *text = "HELLO WORLD!"; static const char *long_text = "It was a bright cold day in April, and the clocks were striking " "thirteen. Winston Smith, his chin nuzzled into his breast in an effort " "to escape the vile wind, slipped quickly through the glass doors of " "Victory Mansions, though not quickly enough to prevent a swirl of " "gritty dust from entering along with him."; LOG_TEST_NAME("test_dump_slice"); expect_slice_dump(gpr_slice_from_copied_string(text), GPR_DUMP_ASCII, text); expect_slice_dump(gpr_slice_from_copied_string(long_text), GPR_DUMP_ASCII, long_text); expect_slice_dump(gpr_slice_from_copied_buffer("\x01", 1), GPR_DUMP_HEX, "01"); expect_slice_dump(gpr_slice_from_copied_buffer("\x01", 1), GPR_DUMP_HEX | GPR_DUMP_ASCII, "01 '.'"); }
static void test_vector(const char *raw, size_t raw_length, const char *encoded, size_t encoded_length, const uint8_t *dict) { char *raw_msg = gpr_dump(raw, raw_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *encoded_msg = gpr_dump(encoded, encoded_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_DEBUG, "Trial:\nraw = %s\nencoded = %s", raw_msg, encoded_msg); gpr_free(raw_msg); gpr_free(encoded_msg); gpr_slice raw_slice = gpr_slice_from_copied_buffer(raw, raw_length); gpr_slice encoded_slice = gpr_slice_from_copied_buffer(encoded, encoded_length); gpr_slice raw2encoded_slice = gpr_percent_encode_slice(raw_slice, dict); gpr_slice encoded2raw_slice; GPR_ASSERT( gpr_strict_percent_decode_slice(encoded_slice, dict, &encoded2raw_slice)); gpr_slice encoded2raw_permissive_slice = gpr_permissive_percent_decode_slice(encoded_slice); char *raw2encoded_msg = gpr_dump_slice(raw2encoded_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *encoded2raw_msg = gpr_dump_slice(encoded2raw_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *encoded2raw_permissive_msg = gpr_dump_slice( encoded2raw_permissive_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_DEBUG, "Result:\nraw2encoded = %s\nencoded2raw = %s\nencoded2raw_permissive " "= %s", raw2encoded_msg, encoded2raw_msg, encoded2raw_permissive_msg); gpr_free(raw2encoded_msg); gpr_free(encoded2raw_msg); gpr_free(encoded2raw_permissive_msg); GPR_ASSERT(0 == gpr_slice_cmp(raw_slice, encoded2raw_slice)); GPR_ASSERT(0 == gpr_slice_cmp(raw_slice, encoded2raw_permissive_slice)); GPR_ASSERT(0 == gpr_slice_cmp(encoded_slice, raw2encoded_slice)); gpr_slice_unref(encoded2raw_slice); gpr_slice_unref(encoded2raw_permissive_slice); gpr_slice_unref(raw2encoded_slice); gpr_slice_unref(raw_slice); gpr_slice_unref(encoded_slice); }
static void plugin_md_request_metadata_ready(void *request, const grpc_metadata *md, size_t num_md, grpc_status_code status, const char *error_details) { /* called from application code */ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_metadata_plugin_request *r = (grpc_metadata_plugin_request *)request; if (status != GRPC_STATUS_OK) { if (error_details != NULL) { gpr_log(GPR_ERROR, "Getting metadata from plugin failed with error: %s", error_details); } r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR, error_details); } else { size_t i; bool seen_illegal_header = false; grpc_credentials_md *md_array = NULL; for (i = 0; i < num_md; i++) { if (!grpc_header_key_is_legal(md[i].key, strlen(md[i].key))) { gpr_log(GPR_ERROR, "Plugin added invalid metadata key: %s", md[i].key); seen_illegal_header = true; break; } else if (!grpc_is_binary_header(md[i].key, strlen(md[i].key)) && !grpc_header_nonbin_value_is_legal(md[i].value, md[i].value_length)) { gpr_log(GPR_ERROR, "Plugin added invalid metadata value."); seen_illegal_header = true; break; } } if (seen_illegal_header) { r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR, "Illegal metadata"); } else if (num_md > 0) { md_array = gpr_malloc(num_md * sizeof(grpc_credentials_md)); for (i = 0; i < num_md; i++) { md_array[i].key = gpr_slice_from_copied_string(md[i].key); md_array[i].value = gpr_slice_from_copied_buffer(md[i].value, md[i].value_length); } r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK, NULL); for (i = 0; i < num_md; i++) { gpr_slice_unref(md_array[i].key); gpr_slice_unref(md_array[i].value); } gpr_free(md_array); } } gpr_free(r); grpc_exec_ctx_finish(&exec_ctx); }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_http_parser parser; grpc_http_request request; memset(&request, 0, sizeof(request)); grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request); gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size); GRPC_ERROR_UNREF(grpc_http_parser_parse(&parser, slice)); GRPC_ERROR_UNREF(grpc_http_parser_eof(&parser)); gpr_slice_unref(slice); grpc_http_parser_destroy(&parser); grpc_http_request_destroy(&request); return 0; }
static void test_varint(uint32_t value, uint32_t prefix_bits, uint8_t prefix_or, const char *expect_bytes, size_t expect_length) { uint32_t nbytes = GRPC_CHTTP2_VARINT_LENGTH(value, prefix_bits); gpr_slice expect = gpr_slice_from_copied_buffer(expect_bytes, expect_length); gpr_slice slice; gpr_log(GPR_DEBUG, "Test: 0x%08x", value); GPR_ASSERT(nbytes == expect_length); slice = gpr_slice_malloc(nbytes); GRPC_CHTTP2_WRITE_VARINT(value, prefix_bits, prefix_or, GPR_SLICE_START_PTR(slice), nbytes); GPR_ASSERT(gpr_slice_cmp(expect, slice) == 0); gpr_slice_unref(expect); gpr_slice_unref(slice); }
/* Takes ownership of the header, claims and signature. */ static verifier_cb_ctx *verifier_cb_ctx_create( grpc_jwt_verifier *verifier, grpc_pollset *pollset, jose_header *header, grpc_jwt_claims *claims, const char *audience, gpr_slice signature, const char *signed_jwt, size_t signed_jwt_len, void *user_data, grpc_jwt_verification_done_cb cb) { verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx)); memset(ctx, 0, sizeof(verifier_cb_ctx)); ctx->verifier = verifier; ctx->pollset = pollset; ctx->header = header; ctx->audience = gpr_strdup(audience); ctx->claims = claims; ctx->signature = signature; ctx->signed_data = gpr_slice_from_copied_buffer(signed_jwt, signed_jwt_len); ctx->user_data = user_data; ctx->user_cb = cb; return ctx; }
static void expect_combined_equiv(const char *s, size_t len, int line) { gpr_slice input = gpr_slice_from_copied_buffer(s, len); gpr_slice base64 = grpc_chttp2_base64_encode(input); gpr_slice expect = grpc_chttp2_huffman_compress(base64); gpr_slice got = grpc_chttp2_base64_encode_and_huffman_compress_impl(input); if (0 != gpr_slice_cmp(expect, got)) { char *t = gpr_dump_slice(input, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *e = gpr_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *g = gpr_dump_slice(got, GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_ERROR, "FAILED:%d:\ntest: %s\ngot: %s\nwant: %s", t, g, e); gpr_free(t); gpr_free(e); gpr_free(g); all_ok = 0; } gpr_slice_unref(input); gpr_slice_unref(base64); gpr_slice_unref(expect); gpr_slice_unref(got); }
/* Takes ownership of the header, claims and signature. */ static verifier_cb_ctx *verifier_cb_ctx_create( grpc_jwt_verifier *verifier, grpc_pollset *pollset, jose_header *header, grpc_jwt_claims *claims, const char *audience, gpr_slice signature, const char *signed_jwt, size_t signed_jwt_len, void *user_data, grpc_jwt_verification_done_cb cb) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx)); memset(ctx, 0, sizeof(verifier_cb_ctx)); ctx->verifier = verifier; ctx->pollent = grpc_polling_entity_create_from_pollset(pollset); ctx->header = header; ctx->audience = gpr_strdup(audience); ctx->claims = claims; ctx->signature = signature; ctx->signed_data = gpr_slice_from_copied_buffer(signed_jwt, signed_jwt_len); ctx->user_data = user_data; ctx->user_cb = cb; grpc_exec_ctx_finish(&exec_ctx); return ctx; }
static void test(const uint8_t *data, size_t size, const uint8_t *dict) { struct grpc_memory_counters counters; grpc_memory_counters_init(); gpr_slice input = gpr_slice_from_copied_buffer((const char *)data, size); gpr_slice output = gpr_percent_encode_slice(input, dict); gpr_slice decoded_output; // encoder must always produce decodable output GPR_ASSERT(gpr_strict_percent_decode_slice(output, dict, &decoded_output)); gpr_slice permissive_decoded_output = gpr_permissive_percent_decode_slice(output); // and decoded output must always match the input GPR_ASSERT(gpr_slice_cmp(input, decoded_output) == 0); GPR_ASSERT(gpr_slice_cmp(input, permissive_decoded_output) == 0); gpr_slice_unref(input); gpr_slice_unref(output); gpr_slice_unref(decoded_output); gpr_slice_unref(permissive_decoded_output); counters = grpc_memory_counters_snapshot(); grpc_memory_counters_destroy(); GPR_ASSERT(counters.total_size_relative == 0); }
static void send_handshake_bytes_to_peer(grpc_secure_transport_setup *s) { size_t offset = 0; tsi_result result = TSI_OK; gpr_slice to_send; grpc_endpoint_write_status write_status; do { size_t to_send_size = s->handshake_buffer_size - offset; result = tsi_handshaker_get_bytes_to_send_to_peer( s->handshaker, s->handshake_buffer + offset, &to_send_size); offset += to_send_size; if (result == TSI_INCOMPLETE_DATA) { s->handshake_buffer_size *= 2; s->handshake_buffer = gpr_realloc(s->handshake_buffer, s->handshake_buffer_size); } } while (result == TSI_INCOMPLETE_DATA); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshake failed with error %s", tsi_result_to_string(result)); secure_transport_setup_done(s, 0); return; } to_send = gpr_slice_from_copied_buffer((const char *)s->handshake_buffer, offset); /* TODO(klempner,jboeuf): This should probably use the client setup deadline */ write_status = grpc_endpoint_write(s->endpoint, &to_send, 1, on_handshake_data_sent_to_peer, s); if (write_status == GRPC_ENDPOINT_WRITE_ERROR) { gpr_log(GPR_ERROR, "Could not send handshake data to peer."); secure_transport_setup_done(s, 0); } else if (write_status == GRPC_ENDPOINT_WRITE_DONE) { on_handshake_data_sent_to_peer(s, GRPC_ENDPOINT_CB_OK); } }
static void expect_combined_equiv(const char *s, size_t len, int line) { gpr_slice input = gpr_slice_from_copied_buffer(s, len); gpr_slice base64 = grpc_chttp2_base64_encode(input); gpr_slice expect = grpc_chttp2_huffman_compress(base64); gpr_slice got = grpc_chttp2_base64_encode_and_huffman_compress(input); if (0 != gpr_slice_cmp(expect, got)) { char *t = gpr_hexdump((const char *)GPR_SLICE_START_PTR(input), GPR_SLICE_LENGTH(input), GPR_HEXDUMP_PLAINTEXT); char *e = gpr_hexdump((const char *)GPR_SLICE_START_PTR(expect), GPR_SLICE_LENGTH(expect), GPR_HEXDUMP_PLAINTEXT); char *g = gpr_hexdump((const char *)GPR_SLICE_START_PTR(got), GPR_SLICE_LENGTH(got), GPR_HEXDUMP_PLAINTEXT); gpr_log(GPR_ERROR, "FAILED:%d:\ntest: %s\ngot: %s\nwant: %s", t, g, e); gpr_free(t); gpr_free(e); gpr_free(g); all_ok = 0; } gpr_slice_unref(input); gpr_slice_unref(base64); gpr_slice_unref(expect); gpr_slice_unref(got); }
static void plugin_md_request_metadata_ready(void *request, const grpc_metadata *md, size_t num_md, grpc_status_code status, const char *error_details) { /* called from application code */ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_metadata_plugin_request *r = (grpc_metadata_plugin_request *)request; if (status != GRPC_STATUS_OK) { if (error_details != NULL) { gpr_log(GPR_ERROR, "Getting metadata from plugin failed with error: %s", error_details); } r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR); } else { size_t i; grpc_credentials_md *md_array = NULL; if (num_md > 0) { md_array = gpr_malloc(num_md * sizeof(grpc_credentials_md)); for (i = 0; i < num_md; i++) { md_array[i].key = gpr_slice_from_copied_string(md[i].key); md_array[i].value = gpr_slice_from_copied_buffer(md[i].value, md[i].value_length); } } r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK); if (md_array != NULL) { for (i = 0; i < num_md; i++) { gpr_slice_unref(md_array[i].key); gpr_slice_unref(md_array[i].value); } gpr_free(md_array); } } gpr_free(r); grpc_exec_ctx_finish(&exec_ctx); }
grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) { gpr_slice slice = gpr_slice_from_copied_buffer(string, length); grpc_byte_buffer *buffer = grpc_byte_buffer_create(&slice, 1); gpr_slice_unref(slice); return buffer; }
int pygrpc_produce_op(PyObject *op, grpc_op *result) { static const int OP_TUPLE_SIZE = 6; static const int STATUS_TUPLE_SIZE = 2; static const int TYPE_INDEX = 0; static const int INITIAL_METADATA_INDEX = 1; static const int TRAILING_METADATA_INDEX = 2; static const int MESSAGE_INDEX = 3; static const int STATUS_INDEX = 4; static const int STATUS_CODE_INDEX = 0; static const int STATUS_DETAILS_INDEX = 1; static const int WRITE_FLAGS_INDEX = 5; int type; Py_ssize_t message_size; char *message; char *status_details; gpr_slice message_slice; grpc_op c_op; if (!PyTuple_Check(op)) { PyErr_SetString(PyExc_TypeError, "expected tuple op"); return 0; } if (PyTuple_Size(op) != OP_TUPLE_SIZE) { char *buf; gpr_asprintf(&buf, "expected tuple op of length %d", OP_TUPLE_SIZE); PyErr_SetString(PyExc_ValueError, buf); gpr_free(buf); return 0; } type = PyInt_AsLong(PyTuple_GET_ITEM(op, TYPE_INDEX)); if (PyErr_Occurred()) { return 0; } c_op.op = type; c_op.flags = PyInt_AsLong(PyTuple_GET_ITEM(op, WRITE_FLAGS_INDEX)); if (PyErr_Occurred()) { return 0; } switch (type) { case GRPC_OP_SEND_INITIAL_METADATA: if (!pygrpc_cast_pyseq_to_send_metadata( PyTuple_GetItem(op, INITIAL_METADATA_INDEX), &c_op.data.send_initial_metadata.metadata, &c_op.data.send_initial_metadata.count)) { return 0; } break; case GRPC_OP_SEND_MESSAGE: PyString_AsStringAndSize( PyTuple_GET_ITEM(op, MESSAGE_INDEX), &message, &message_size); message_slice = gpr_slice_from_copied_buffer(message, message_size); c_op.data.send_message = grpc_raw_byte_buffer_create(&message_slice, 1); gpr_slice_unref(message_slice); break; case GRPC_OP_SEND_CLOSE_FROM_CLIENT: /* Don't need to fill in any other fields. */ break; case GRPC_OP_SEND_STATUS_FROM_SERVER: if (!pygrpc_cast_pyseq_to_send_metadata( PyTuple_GetItem(op, TRAILING_METADATA_INDEX), &c_op.data.send_status_from_server.trailing_metadata, &c_op.data.send_status_from_server.trailing_metadata_count)) { return 0; } if (!PyTuple_Check(PyTuple_GET_ITEM(op, STATUS_INDEX))) { char *buf; gpr_asprintf(&buf, "expected tuple status in op of length %d", STATUS_TUPLE_SIZE); PyErr_SetString(PyExc_ValueError, buf); gpr_free(buf); return 0; } c_op.data.send_status_from_server.status = PyInt_AsLong( PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_CODE_INDEX)); status_details = PyString_AsString( PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_DETAILS_INDEX)); if (PyErr_Occurred()) { return 0; } c_op.data.send_status_from_server.status_details = gpr_malloc(strlen(status_details) + 1); strcpy((char *)c_op.data.send_status_from_server.status_details, status_details); break; case GRPC_OP_RECV_INITIAL_METADATA: c_op.data.recv_initial_metadata = gpr_malloc(sizeof(grpc_metadata_array)); grpc_metadata_array_init(c_op.data.recv_initial_metadata); break; case GRPC_OP_RECV_MESSAGE: c_op.data.recv_message = gpr_malloc(sizeof(grpc_byte_buffer *)); break; case GRPC_OP_RECV_STATUS_ON_CLIENT: c_op.data.recv_status_on_client.trailing_metadata = gpr_malloc(sizeof(grpc_metadata_array)); grpc_metadata_array_init(c_op.data.recv_status_on_client.trailing_metadata); c_op.data.recv_status_on_client.status = gpr_malloc(sizeof(grpc_status_code *)); c_op.data.recv_status_on_client.status_details = gpr_malloc(sizeof(char *)); *c_op.data.recv_status_on_client.status_details = NULL; c_op.data.recv_status_on_client.status_details_capacity = gpr_malloc(sizeof(size_t)); *c_op.data.recv_status_on_client.status_details_capacity = 0; break; case GRPC_OP_RECV_CLOSE_ON_SERVER: c_op.data.recv_close_on_server.cancelled = gpr_malloc(sizeof(int)); break; default: return 0; } *result = c_op; return 1; }
gpr_slice gpr_slice_from_copied_string(const char *source) { return gpr_slice_from_copied_buffer(source, strlen(source)); }
grpc_byte_buffer *string_to_byte_buffer(const char *buffer, size_t len) { gpr_slice slice = gpr_slice_from_copied_buffer(buffer, len); grpc_byte_buffer *bb = grpc_raw_byte_buffer_create(&slice, 1); gpr_slice_unref(slice); return bb; }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_test_only_set_metadata_hash_seed(0); struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); if (leak_check) grpc_memory_counters_init(); grpc_init(); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_resource_quota *resource_quota = grpc_resource_quota_create("server_fuzzer"); grpc_endpoint *mock_endpoint = grpc_mock_endpoint_create(discard_write, resource_quota); grpc_resource_quota_internal_unref(&exec_ctx, resource_quota); grpc_mock_endpoint_put_read( &exec_ctx, mock_endpoint, gpr_slice_from_copied_buffer((const char *)data, size)); grpc_server *server = grpc_server_create(NULL, NULL); grpc_completion_queue *cq = grpc_completion_queue_create(NULL); grpc_server_register_completion_queue(server, cq, NULL); // TODO(ctiller): add registered methods (one for POST, one for PUT) // void *registered_method = // grpc_server_register_method(server, "/reg", NULL, 0); grpc_server_start(server); grpc_transport *transport = grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 0); grpc_server_setup_transport(&exec_ctx, server, transport, NULL, NULL); grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_call *call1 = NULL; grpc_call_details call_details1; grpc_metadata_array request_metadata1; grpc_call_details_init(&call_details1); grpc_metadata_array_init(&request_metadata1); int requested_calls = 0; grpc_server_request_call(server, &call1, &call_details1, &request_metadata1, cq, cq, tag(1)); requested_calls++; grpc_event ev; while (1) { grpc_exec_ctx_flush(&exec_ctx); ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL); switch (ev.type) { case GRPC_QUEUE_TIMEOUT: goto done; case GRPC_QUEUE_SHUTDOWN: break; case GRPC_OP_COMPLETE: switch (detag(ev.tag)) { case 1: requested_calls--; // TODO(ctiller): keep reading that call! break; } } } done: if (call1 != NULL) grpc_call_destroy(call1); grpc_call_details_destroy(&call_details1); grpc_metadata_array_destroy(&request_metadata1); grpc_server_shutdown_and_notify(server, cq, tag(0xdead)); grpc_server_cancel_all_calls(server); for (int i = 0; i <= requested_calls; i++) { ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL); GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); } grpc_completion_queue_shutdown(cq); for (int i = 0; i <= requested_calls; i++) { ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL); GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN); } grpc_server_destroy(server); grpc_completion_queue_destroy(cq); grpc_shutdown(); if (leak_check) { counters = grpc_memory_counters_snapshot(); grpc_memory_counters_destroy(); GPR_ASSERT(counters.total_size_relative == 0); } return 0; }
static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair( size_t slice_size, gpr_slice *leftover_slices, size_t leftover_nslices) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; tsi_frame_protector *fake_read_protector = tsi_create_fake_protector(NULL); tsi_frame_protector *fake_write_protector = tsi_create_fake_protector(NULL); grpc_endpoint_test_fixture f; grpc_endpoint_pair tcp; tcp = grpc_iomgr_create_endpoint_pair("fixture", slice_size); grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, g_pollset); grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, g_pollset); if (leftover_nslices == 0) { f.client_ep = grpc_secure_endpoint_create(fake_read_protector, tcp.client, NULL, 0); } else { unsigned i; tsi_result result; size_t still_pending_size; size_t total_buffer_size = 8192; size_t buffer_size = total_buffer_size; uint8_t *encrypted_buffer = gpr_malloc(buffer_size); uint8_t *cur = encrypted_buffer; gpr_slice encrypted_leftover; for (i = 0; i < leftover_nslices; i++) { gpr_slice plain = leftover_slices[i]; uint8_t *message_bytes = GPR_SLICE_START_PTR(plain); size_t message_size = GPR_SLICE_LENGTH(plain); while (message_size > 0) { size_t protected_buffer_size_to_send = buffer_size; size_t processed_message_size = message_size; result = tsi_frame_protector_protect( fake_write_protector, message_bytes, &processed_message_size, cur, &protected_buffer_size_to_send); GPR_ASSERT(result == TSI_OK); message_bytes += processed_message_size; message_size -= processed_message_size; cur += protected_buffer_size_to_send; GPR_ASSERT(buffer_size >= protected_buffer_size_to_send); buffer_size -= protected_buffer_size_to_send; } gpr_slice_unref(plain); } do { size_t protected_buffer_size_to_send = buffer_size; result = tsi_frame_protector_protect_flush(fake_write_protector, cur, &protected_buffer_size_to_send, &still_pending_size); GPR_ASSERT(result == TSI_OK); cur += protected_buffer_size_to_send; GPR_ASSERT(buffer_size >= protected_buffer_size_to_send); buffer_size -= protected_buffer_size_to_send; } while (still_pending_size > 0); encrypted_leftover = gpr_slice_from_copied_buffer( (const char *)encrypted_buffer, total_buffer_size - buffer_size); f.client_ep = grpc_secure_endpoint_create(fake_read_protector, tcp.client, &encrypted_leftover, 1); gpr_slice_unref(encrypted_leftover); gpr_free(encrypted_buffer); } f.server_ep = grpc_secure_endpoint_create(fake_write_protector, tcp.server, NULL, 0); grpc_exec_ctx_finish(&exec_ctx); return f; }
void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator, const char *client_payload, size_t client_payload_length, gpr_uint32 flags) { grpc_endpoint_pair sfd; thd_args a; gpr_thd_id id; char *hex; grpc_transport *transport; grpc_mdctx *mdctx = grpc_mdctx_create(); gpr_slice slice = gpr_slice_from_copied_buffer(client_payload, client_payload_length); hex = gpr_dump(client_payload, client_payload_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); /* Add a debug log */ gpr_log(GPR_INFO, "TEST: %s", hex); gpr_free(hex); /* Init grpc */ grpc_init(); /* Create endpoints */ sfd = grpc_iomgr_create_endpoint_pair("fixture", 65536); /* Create server, completion events */ a.server = grpc_server_create_from_filters(NULL, 0, NULL); a.cq = grpc_completion_queue_create(NULL); gpr_event_init(&a.done_thd); gpr_event_init(&a.done_write); a.validator = validator; grpc_server_register_completion_queue(a.server, a.cq, NULL); grpc_server_start(a.server); transport = grpc_create_chttp2_transport(NULL, sfd.server, mdctx, 0); server_setup_transport(&a, transport, mdctx); grpc_chttp2_transport_start_reading(transport, NULL, 0); /* Bind everything into the same pollset */ grpc_endpoint_add_to_pollset(sfd.client, grpc_cq_pollset(a.cq)); grpc_endpoint_add_to_pollset(sfd.server, grpc_cq_pollset(a.cq)); /* Check a ground truth */ GPR_ASSERT(grpc_server_has_open_connections(a.server)); /* Start validator */ gpr_thd_new(&id, thd_func, &a, NULL); /* Write data */ switch (grpc_endpoint_write(sfd.client, &slice, 1, done_write, &a)) { case GRPC_ENDPOINT_WRITE_DONE: done_write(&a, 1); break; case GRPC_ENDPOINT_WRITE_PENDING: break; case GRPC_ENDPOINT_WRITE_ERROR: done_write(&a, 0); break; } /* Await completion */ GPR_ASSERT( gpr_event_wait(&a.done_write, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))); if (flags & GRPC_BAD_CLIENT_DISCONNECT) { grpc_endpoint_destroy(sfd.client); sfd.client = NULL; } GPR_ASSERT(gpr_event_wait(&a.done_thd, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))); /* Shutdown */ if (sfd.client) { grpc_endpoint_destroy(sfd.client); } grpc_server_shutdown_and_notify(a.server, a.cq, NULL); GPR_ASSERT(grpc_completion_queue_pluck( a.cq, NULL, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL) .type == GRPC_OP_COMPLETE); grpc_server_destroy(a.server); grpc_completion_queue_destroy(a.cq); grpc_shutdown(); }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_test_only_set_metadata_hash_seed(0); struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); grpc_memory_counters_init(); grpc_init(); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_endpoint *mock_endpoint = grpc_mock_endpoint_create(discard_write); grpc_completion_queue *cq = grpc_completion_queue_create(NULL); grpc_transport *transport = grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 1); grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); grpc_channel *channel = grpc_channel_create( &exec_ctx, "test-target", NULL, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_call *call = grpc_channel_create_call(channel, NULL, 0, cq, "/foo", "localhost", gpr_inf_future(GPR_CLOCK_REALTIME), NULL); grpc_metadata_array initial_metadata_recv; grpc_metadata_array_init(&initial_metadata_recv); grpc_byte_buffer *response_payload_recv = NULL; grpc_metadata_array trailing_metadata_recv; grpc_metadata_array_init(&trailing_metadata_recv); grpc_status_code status; char *details = NULL; size_t details_capacity = 0; grpc_op ops[6]; memset(ops, 0, sizeof(ops)); grpc_op *op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_RECV_INITIAL_METADATA; op->data.recv_initial_metadata = &initial_metadata_recv; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message = &response_payload_recv; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; op->data.recv_status_on_client.status = &status; op->data.recv_status_on_client.status_details = &details; op->data.recv_status_on_client.status_details_capacity = &details_capacity; op->flags = 0; op->reserved = NULL; op++; grpc_call_error error = grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(1), NULL); int requested_calls = 1; GPR_ASSERT(GRPC_CALL_OK == error); grpc_mock_endpoint_put_read( &exec_ctx, mock_endpoint, gpr_slice_from_copied_buffer((const char *)data, size)); grpc_event ev; while (1) { grpc_exec_ctx_flush(&exec_ctx); ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL); switch (ev.type) { case GRPC_QUEUE_TIMEOUT: goto done; case GRPC_QUEUE_SHUTDOWN: break; case GRPC_OP_COMPLETE: requested_calls--; break; } } done: if (requested_calls) { grpc_call_cancel(call, NULL); } for (int i = 0; i < requested_calls; i++) { ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL); GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); } grpc_completion_queue_shutdown(cq); for (int i = 0; i < requested_calls; i++) { ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL); GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN); } grpc_call_destroy(call); grpc_completion_queue_destroy(cq); grpc_metadata_array_destroy(&initial_metadata_recv); grpc_metadata_array_destroy(&trailing_metadata_recv); gpr_free(details); grpc_channel_destroy(channel); if (response_payload_recv != NULL) { grpc_byte_buffer_destroy(response_payload_recv); } grpc_shutdown(); counters = grpc_memory_counters_snapshot(); grpc_memory_counters_destroy(); GPR_ASSERT(counters.total_size_relative == 0); return 0; }
void grpc_run_bad_client_test(const char *name, const char *client_payload, size_t client_payload_length, grpc_bad_client_server_side_validator validator) { grpc_endpoint_pair sfd; thd_args a; gpr_thd_id id; gpr_slice slice = gpr_slice_from_copied_buffer(client_payload, client_payload_length); /* Add a debug log */ gpr_log(GPR_INFO, "TEST: %s", name); /* Init grpc */ grpc_init(); /* Create endpoints */ sfd = grpc_iomgr_create_endpoint_pair(65536); /* Create server, completion events */ a.server = grpc_server_create_from_filters(NULL, 0, NULL); a.cq = grpc_completion_queue_create(); gpr_event_init(&a.done_thd); gpr_event_init(&a.done_write); a.validator = validator; grpc_server_register_completion_queue(a.server, a.cq); grpc_server_start(a.server); grpc_create_chttp2_transport(server_setup_transport, &a, NULL, sfd.server, NULL, 0, grpc_mdctx_create(), 0); /* Bind everything into the same pollset */ grpc_endpoint_add_to_pollset(sfd.client, grpc_cq_pollset(a.cq)); grpc_endpoint_add_to_pollset(sfd.server, grpc_cq_pollset(a.cq)); /* Check a ground truth */ GPR_ASSERT(grpc_server_has_open_connections(a.server)); /* Start validator */ gpr_thd_new(&id, thd_func, &a, NULL); /* Write data */ switch (grpc_endpoint_write(sfd.client, &slice, 1, done_write, &a)) { case GRPC_ENDPOINT_WRITE_DONE: done_write(&a, 1); break; case GRPC_ENDPOINT_WRITE_PENDING: break; case GRPC_ENDPOINT_WRITE_ERROR: done_write(&a, 0); break; } /* Await completion */ GPR_ASSERT( gpr_event_wait(&a.done_write, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))); GPR_ASSERT(gpr_event_wait(&a.done_thd, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))); /* Shutdown */ grpc_endpoint_destroy(sfd.client); grpc_server_destroy(a.server); grpc_completion_queue_destroy(a.cq); grpc_shutdown(); }
void grpc_run_bad_client_test( grpc_bad_client_server_side_validator server_validator, grpc_bad_client_client_stream_validator client_validator, const char *client_payload, size_t client_payload_length, uint32_t flags) { grpc_endpoint_pair sfd; thd_args a; gpr_thd_id id; char *hex; grpc_transport *transport; gpr_slice slice = gpr_slice_from_copied_buffer(client_payload, client_payload_length); gpr_slice_buffer outgoing; grpc_closure done_write_closure; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; hex = gpr_dump(client_payload, client_payload_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); /* Add a debug log */ gpr_log(GPR_INFO, "TEST: %s", hex); gpr_free(hex); /* Init grpc */ grpc_init(); /* Create endpoints */ sfd = grpc_iomgr_create_endpoint_pair("fixture", 65536); /* Create server, completion events */ a.server = grpc_server_create(NULL, NULL); a.cq = grpc_completion_queue_create(NULL); gpr_event_init(&a.done_thd); gpr_event_init(&a.done_write); a.validator = server_validator; grpc_server_register_completion_queue(a.server, a.cq, NULL); a.registered_method = grpc_server_register_method(a.server, GRPC_BAD_CLIENT_REGISTERED_METHOD, GRPC_BAD_CLIENT_REGISTERED_HOST, GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, 0); grpc_server_start(a.server); transport = grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, 0); server_setup_transport(&a, transport); grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); /* Bind everything into the same pollset */ grpc_endpoint_add_to_pollset(&exec_ctx, sfd.client, grpc_cq_pollset(a.cq)); grpc_endpoint_add_to_pollset(&exec_ctx, sfd.server, grpc_cq_pollset(a.cq)); /* Check a ground truth */ GPR_ASSERT(grpc_server_has_open_connections(a.server)); /* Start validator */ gpr_thd_new(&id, thd_func, &a, NULL); gpr_slice_buffer_init(&outgoing); gpr_slice_buffer_add(&outgoing, slice); grpc_closure_init(&done_write_closure, done_write, &a); /* Write data */ grpc_endpoint_write(&exec_ctx, sfd.client, &outgoing, &done_write_closure); grpc_exec_ctx_finish(&exec_ctx); /* Await completion */ GPR_ASSERT( gpr_event_wait(&a.done_write, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))); if (flags & GRPC_BAD_CLIENT_DISCONNECT) { grpc_endpoint_shutdown(&exec_ctx, sfd.client); grpc_endpoint_destroy(&exec_ctx, sfd.client); grpc_exec_ctx_finish(&exec_ctx); sfd.client = NULL; } GPR_ASSERT(gpr_event_wait(&a.done_thd, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))); if (sfd.client != NULL) { // Validate client stream, if requested. if (client_validator != NULL) { read_args args; args.validator = client_validator; gpr_slice_buffer_init(&args.incoming); gpr_event_init(&args.read_done); grpc_closure read_done_closure; grpc_closure_init(&read_done_closure, read_done, &args); grpc_endpoint_read(&exec_ctx, sfd.client, &args.incoming, &read_done_closure); grpc_exec_ctx_finish(&exec_ctx); GPR_ASSERT( gpr_event_wait(&args.read_done, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))); gpr_slice_buffer_destroy(&args.incoming); } // Shutdown. grpc_endpoint_shutdown(&exec_ctx, sfd.client); grpc_endpoint_destroy(&exec_ctx, sfd.client); grpc_exec_ctx_finish(&exec_ctx); } grpc_server_shutdown_and_notify(a.server, a.cq, NULL); GPR_ASSERT(grpc_completion_queue_pluck( a.cq, NULL, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL) .type == GRPC_OP_COMPLETE); grpc_server_destroy(a.server); grpc_completion_queue_destroy(a.cq); gpr_slice_buffer_destroy(&outgoing); grpc_exec_ctx_finish(&exec_ctx); grpc_shutdown(); }