/* Create a call given a grpc_channel, in order to call method. The request is not sent until grpc_call_invoke is called. */ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent, VALUE mask, VALUE method, VALUE host, VALUE deadline) { VALUE res = Qnil; grpc_rb_channel *wrapper = NULL; grpc_call *call = NULL; grpc_call *parent_call = NULL; grpc_completion_queue *cq = NULL; int flags = GRPC_PROPAGATE_DEFAULTS; grpc_slice method_slice; grpc_slice host_slice; grpc_slice *host_slice_ptr = NULL; char *tmp_str = NULL; if (host != Qnil) { host_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(host), RSTRING_LEN(host)); host_slice_ptr = &host_slice; } if (mask != Qnil) { flags = NUM2UINT(mask); } if (parent != Qnil) { parent_call = grpc_rb_get_wrapped_call(parent); } cq = grpc_completion_queue_create_for_pluck(NULL); TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper); if (wrapper->bg_wrapped == NULL) { rb_raise(rb_eRuntimeError, "closed!"); return Qnil; } method_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(method), RSTRING_LEN(method)); call = grpc_channel_create_call(wrapper->bg_wrapped->channel, parent_call, flags, cq, method_slice, host_slice_ptr, grpc_rb_time_timeval(deadline, /* absolute time */ 0), NULL); if (call == NULL) { tmp_str = grpc_slice_to_c_string(method_slice); rb_raise(rb_eRuntimeError, "cannot create call with method %s", tmp_str); return Qnil; } grpc_slice_unref(method_slice); if (host_slice_ptr != NULL) { grpc_slice_unref(host_slice); } res = grpc_rb_wrap_call(call, cq); /* Make this channel an instance attribute of the call so that it is not GCed * before the call. */ rb_ivar_set(res, id_channel, self); return res; }
/* grpc_rb_op_update_status_from_server adds the values in a ruby status struct to the 'send_status_from_server' portion of an op. */ static void grpc_rb_op_update_status_from_server( grpc_op *op, grpc_metadata_array *md_ary, grpc_slice *send_status_details, VALUE status) { VALUE code = rb_struct_aref(status, sym_code); VALUE details = rb_struct_aref(status, sym_details); VALUE metadata_hash = rb_struct_aref(status, sym_metadata); /* TODO: add check to ensure status is the correct struct type */ if (TYPE(code) != T_FIXNUM) { rb_raise(rb_eTypeError, "invalid code : got <%s>, want <Fixnum>", rb_obj_classname(code)); return; } if (TYPE(details) != T_STRING) { rb_raise(rb_eTypeError, "invalid details : got <%s>, want <String>", rb_obj_classname(code)); return; } *send_status_details = grpc_slice_from_copied_buffer(RSTRING_PTR(details), RSTRING_LEN(details)); op->data.send_status_from_server.status = NUM2INT(code); op->data.send_status_from_server.status_details = send_status_details; grpc_rb_md_ary_convert(metadata_hash, md_ary); op->data.send_status_from_server.trailing_metadata_count = md_ary->count; op->data.send_status_from_server.trailing_metadata = md_ary->metadata; }
static grpc_error *send_handshake_bytes_to_peer_locked(grpc_exec_ctx *exec_ctx, security_handshaker *h) { // Get data to send. tsi_result result = TSI_OK; size_t offset = 0; 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) { return grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Handshake failed"), result); } // Send data. grpc_slice to_send = grpc_slice_from_copied_buffer((const char *)h->handshake_buffer, offset); grpc_slice_buffer_reset_and_unref(&h->outgoing); grpc_slice_buffer_add(&h->outgoing, to_send); grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing, &h->on_handshake_data_sent_to_peer); return GRPC_ERROR_NONE; }
/* Gets the internal value of a compression algorithm suitable as the value * in a GRPC core channel arguments hash. * algorithm_value is an out parameter. * Raises an error if the name of the algorithm passed in is invalid. */ void grpc_rb_compression_options_algorithm_name_to_value_internal( grpc_compression_algorithm* algorithm_value, VALUE algorithm_name) { grpc_slice name_slice; VALUE algorithm_name_as_string = Qnil; Check_Type(algorithm_name, T_SYMBOL); /* Convert the algorithm symbol to a ruby string, so that we can get the * correct C string out of it. */ algorithm_name_as_string = rb_funcall(algorithm_name, rb_intern("to_s"), 0); name_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(algorithm_name_as_string), RSTRING_LEN(algorithm_name_as_string)); /* Raise an error if the name isn't recognized as a compression algorithm by * the algorithm parse function * in GRPC core. */ if (!grpc_compression_algorithm_parse(name_slice, algorithm_value)) { char* name_slice_str = grpc_slice_to_c_string(name_slice); char* error_message_str = NULL; VALUE error_message_ruby_str = Qnil; GPR_ASSERT(gpr_asprintf(&error_message_str, "Invalid compression algorithm name: %s", name_slice_str) != -1); gpr_free(name_slice_str); error_message_ruby_str = rb_str_new(error_message_str, strlen(error_message_str)); gpr_free(error_message_str); rb_raise(rb_eNameError, "%s", StringValueCStr(error_message_ruby_str)); } grpc_slice_unref(name_slice); }
GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_array_add(grpc_metadata_array* array, const char* key, const char* value, size_t value_length) { size_t i = array->count; GPR_ASSERT(array->count < array->capacity); array->metadata[i].key = grpc_slice_from_copied_string(key); array->metadata[i].value = grpc_slice_from_copied_buffer(value, value_length); array->count++; }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (squelch) gpr_set_log_function(dont_log); grpc_slice slice = grpc_slice_from_copied_buffer((const char *)data, size); grpc_grpclb_serverlist *serverlist; if ((serverlist = grpc_grpclb_response_parse_serverlist(slice))) { grpc_grpclb_destroy_serverlist(serverlist); } grpc_slice_unref(slice); return 0; }
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(grpc_slice_from_copied_string(text), GPR_DUMP_ASCII, text); expect_slice_dump(grpc_slice_from_copied_string(long_text), GPR_DUMP_ASCII, long_text); expect_slice_dump(grpc_slice_from_copied_buffer("\x01", 1), GPR_DUMP_HEX, "01"); expect_slice_dump(grpc_slice_from_copied_buffer("\x01", 1), GPR_DUMP_HEX | GPR_DUMP_ASCII, "01 '.'"); }
static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { security_handshaker *h = arg; gpr_mu_lock(&h->mu); if (error != GRPC_ERROR_NONE || h->shutdown) { security_handshake_failed_locked(exec_ctx, h, GRPC_ERROR_REF(error)); goto done; } // Create frame protector. tsi_frame_protector *protector; tsi_result result = tsi_handshaker_result_create_frame_protector( h->handshaker_result, NULL, &protector); if (result != TSI_OK) { error = grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Frame protector creation failed"), result); security_handshake_failed_locked(exec_ctx, h, error); goto done; } // Get unused bytes. unsigned char *unused_bytes = NULL; size_t unused_bytes_size = 0; result = tsi_handshaker_result_get_unused_bytes( h->handshaker_result, &unused_bytes, &unused_bytes_size); // Create secure endpoint. if (unused_bytes_size > 0) { grpc_slice slice = grpc_slice_from_copied_buffer((char *)unused_bytes, unused_bytes_size); h->args->endpoint = grpc_secure_endpoint_create(protector, h->args->endpoint, &slice, 1); grpc_slice_unref_internal(exec_ctx, slice); } else { h->args->endpoint = grpc_secure_endpoint_create(protector, h->args->endpoint, NULL, 0); } tsi_handshaker_result_destroy(h->handshaker_result); h->handshaker_result = NULL; // Clear out the read buffer before it gets passed to the transport. grpc_slice_buffer_reset_and_unref_internal(exec_ctx, h->args->read_buffer); // Add auth context to channel args. grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context); grpc_channel_args *tmp_args = h->args->args; h->args->args = grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1); grpc_channel_args_destroy(exec_ctx, tmp_args); // Invoke callback. GRPC_CLOSURE_SCHED(exec_ctx, h->on_handshake_done, GRPC_ERROR_NONE); // Set shutdown to true so that subsequent calls to // security_handshaker_shutdown() do nothing. h->shutdown = true; done: gpr_mu_unlock(&h->mu); security_handshaker_unref(exec_ctx, h); }
/** Returns a copy of percent decoded \a src[begin, end) */ static char *decode_and_copy_component(grpc_exec_ctx *exec_ctx, const char *src, size_t begin, size_t end) { grpc_slice component = grpc_slice_from_copied_buffer(src + begin, end - begin); grpc_slice decoded_component = grpc_permissive_percent_decode_slice(component); char *out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII); grpc_slice_unref_internal(exec_ctx, component); grpc_slice_unref_internal(exec_ctx, decoded_component); return out; }
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); grpc_slice expect = grpc_slice_from_copied_buffer(expect_bytes, expect_length); grpc_slice slice; gpr_log(GPR_DEBUG, "Test: 0x%08x", value); GPR_ASSERT(nbytes == expect_length); slice = grpc_slice_malloc(nbytes); GRPC_CHTTP2_WRITE_VARINT(value, prefix_bits, prefix_or, GRPC_SLICE_START_PTR(slice), nbytes); GPR_ASSERT(grpc_slice_cmp(expect, slice) == 0); grpc_slice_unref(expect); grpc_slice_unref(slice); }
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server( grpc_call* call, grpcsharp_batch_context* ctx, grpc_status_code status_code, const char* status_details, size_t status_details_len, grpc_metadata_array* trailing_metadata, int32_t send_empty_initial_metadata, const char* optional_send_buffer, size_t optional_send_buffer_len, uint32_t write_flags) { /* TODO: don't use magic number */ grpc_op ops[3]; memset(ops, 0, sizeof(ops)); size_t nops = 1; grpc_slice status_details_slice = grpc_slice_from_copied_buffer(status_details, status_details_len); ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER; ops[0].data.send_status_from_server.status = status_code; ops[0].data.send_status_from_server.status_details = &status_details_slice; grpcsharp_metadata_array_move( &(ctx->send_status_from_server.trailing_metadata), trailing_metadata); ops[0].data.send_status_from_server.trailing_metadata_count = ctx->send_status_from_server.trailing_metadata.count; ops[0].data.send_status_from_server.trailing_metadata = ctx->send_status_from_server.trailing_metadata.metadata; ops[0].flags = 0; ops[0].reserved = NULL; if (optional_send_buffer) { ops[nops].op = GRPC_OP_SEND_MESSAGE; ctx->send_message = string_to_byte_buffer(optional_send_buffer, optional_send_buffer_len); ops[nops].data.send_message.send_message = ctx->send_message; ops[nops].flags = write_flags; ops[nops].reserved = NULL; nops++; } if (send_empty_initial_metadata) { ops[nops].op = GRPC_OP_SEND_INITIAL_METADATA; ops[nops].flags = 0; ops[nops].reserved = NULL; nops++; } grpc_call_error ret = grpcsharp_call_start_batch(call, ops, nops, ctx, NULL); grpc_slice_unref(status_details_slice); return ret; }
/* 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, grpc_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 = grpc_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; }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { struct grpc_memory_counters counters; grpc_memory_counters_init(); grpc_slice input = grpc_slice_from_copied_buffer((const char *)data, size); grpc_slice output; if (grpc_strict_percent_decode_slice( input, grpc_url_percent_encoding_unreserved_bytes, &output)) { grpc_slice_unref(output); } if (grpc_strict_percent_decode_slice( input, grpc_compatible_percent_encoding_unreserved_bytes, &output)) { grpc_slice_unref(output); } grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); grpc_slice_unref(input); counters = grpc_memory_counters_snapshot(); grpc_memory_counters_destroy(); GPR_ASSERT(counters.total_size_relative == 0); return 0; }
static void expect_combined_equiv(const char *s, size_t len, int line) { grpc_slice input = grpc_slice_from_copied_buffer(s, len); grpc_slice base64 = grpc_chttp2_base64_encode(input); grpc_slice expect = grpc_chttp2_huffman_compress(base64); grpc_slice got = grpc_chttp2_base64_encode_and_huffman_compress_impl(input); if (0 != grpc_slice_cmp(expect, got)) { char *t = grpc_dump_slice(input, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *e = grpc_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *g = grpc_dump_slice(got, GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_ERROR, "FAILED:%d:\ntest: %s\ngot: %s\nwant: %s", line, t, g, e); gpr_free(t); gpr_free(e); gpr_free(g); all_ok = 0; } grpc_slice_unref(input); grpc_slice_unref(base64); grpc_slice_unref(expect); grpc_slice_unref(got); }
static grpc_error *on_handshake_next_done_locked( grpc_exec_ctx *exec_ctx, security_handshaker *h, tsi_result result, const unsigned char *bytes_to_send, size_t bytes_to_send_size, tsi_handshaker_result *handshaker_result) { grpc_error *error = GRPC_ERROR_NONE; // Read more if we need to. if (result == TSI_INCOMPLETE_DATA) { GPR_ASSERT(bytes_to_send_size == 0); grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer, &h->on_handshake_data_received_from_peer); return error; } if (result != TSI_OK) { return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result); } // Update handshaker result. if (handshaker_result != NULL) { GPR_ASSERT(h->handshaker_result == NULL); h->handshaker_result = handshaker_result; } if (bytes_to_send_size > 0) { // Send data to peer, if needed. grpc_slice to_send = grpc_slice_from_copied_buffer( (const char *)bytes_to_send, bytes_to_send_size); grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &h->outgoing); grpc_slice_buffer_add(&h->outgoing, to_send); grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing, &h->on_handshake_data_sent_to_peer); } else if (handshaker_result == NULL) { // There is nothing to send, but need to read from peer. grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer, &h->on_handshake_data_received_from_peer); } else { // Handshake has finished, check peer and so on. error = check_peer_locked(exec_ctx, h); } return error; }
grpc_byte_buffer* string_to_byte_buffer(const char* buffer, size_t len) { grpc_slice slice = grpc_slice_from_copied_buffer(buffer, len); grpc_byte_buffer* bb = grpc_raw_byte_buffer_create(&slice, 1); grpc_slice_unref(slice); return bb; }
grpc_slice grpc_slice_from_copied_string(const char *source) { return grpc_slice_from_copied_buffer(source, strlen(source)); }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_test_only_set_slice_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_executor_set_threading(&exec_ctx, false); 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_unref_internal(&exec_ctx, resource_quota); grpc_mock_endpoint_put_read( &exec_ctx, mock_endpoint, grpc_slice_from_copied_buffer((const char *)data, size)); grpc_server *server = grpc_server_create(NULL, NULL); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(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; GPR_ASSERT(GRPC_CALL_OK == 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_unref(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; }
/* grpc_rb_md_ary_fill_hash_cb is the hash iteration callback used to fill grpc_metadata_array. it's capacity should have been computed via a prior call to grpc_rb_md_ary_fill_hash_cb */ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) { grpc_metadata_array *md_ary = NULL; long array_length; long i; grpc_slice key_slice; grpc_slice value_slice; char *tmp_str; if (TYPE(key) == T_SYMBOL) { key_slice = grpc_slice_from_static_string(rb_id2name(SYM2ID(key))); } else if (TYPE(key) == T_STRING) { key_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(key), RSTRING_LEN(key)); } else { rb_raise(rb_eTypeError, "grpc_rb_md_ary_fill_hash_cb: bad type for key parameter"); } if (!grpc_header_key_is_legal(key_slice)) { tmp_str = grpc_slice_to_c_string(key_slice); rb_raise(rb_eArgError, "'%s' is an invalid header key, must match [a-z0-9-_.]+", tmp_str); return ST_STOP; } /* Construct a metadata object from key and value and add it */ TypedData_Get_Struct(md_ary_obj, grpc_metadata_array, &grpc_rb_md_ary_data_type, md_ary); if (TYPE(val) == T_ARRAY) { array_length = RARRAY_LEN(val); /* If the value is an array, add capacity for each value in the array */ for (i = 0; i < array_length; i++) { value_slice = grpc_slice_from_copied_buffer( RSTRING_PTR(rb_ary_entry(val, i)), RSTRING_LEN(rb_ary_entry(val, i))); if (!grpc_is_binary_header(key_slice) && !grpc_header_nonbin_value_is_legal(value_slice)) { // The value has invalid characters tmp_str = grpc_slice_to_c_string(value_slice); rb_raise(rb_eArgError, "Header value '%s' has invalid characters", tmp_str); return ST_STOP; } md_ary->metadata[md_ary->count].key = key_slice; md_ary->metadata[md_ary->count].value = value_slice; md_ary->count += 1; } } else if (TYPE(val) == T_STRING) { value_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(val), RSTRING_LEN(val)); if (!grpc_is_binary_header(key_slice) && !grpc_header_nonbin_value_is_legal(value_slice)) { // The value has invalid characters tmp_str = grpc_slice_to_c_string(value_slice); rb_raise(rb_eArgError, "Header value '%s' has invalid characters", tmp_str); return ST_STOP; } md_ary->metadata[md_ary->count].key = key_slice; md_ary->metadata[md_ary->count].value = value_slice; md_ary->count += 1; } else { rb_raise(rb_eArgError, "Header values must be of type string or array"); return ST_STOP; } return ST_CONTINUE; }
static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair( size_t slice_size, grpc_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; grpc_resource_quota *resource_quota = grpc_resource_quota_create("secure_endpoint_test"); tcp = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, slice_size); grpc_resource_quota_unref_internal(&exec_ctx, resource_quota); 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; grpc_slice encrypted_leftover; for (i = 0; i < leftover_nslices; i++) { grpc_slice plain = leftover_slices[i]; uint8_t *message_bytes = GRPC_SLICE_START_PTR(plain); size_t message_size = GRPC_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; } grpc_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 = grpc_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); grpc_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; }
grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) { grpc_slice slice = grpc_slice_from_copied_buffer(string, length); grpc_byte_buffer *buffer = grpc_raw_byte_buffer_create(&slice, 1); grpc_slice_unref(slice); return buffer; }